proxygen
folly::SerialExecutor Class Reference

Executor that guarantees serial non-concurrent execution of added tasks. More...

#include <SerialExecutor.h>

Inheritance diagram for folly::SerialExecutor:
folly::SequencedExecutor folly::Executor

Classes

class  Deleter
 

Public Types

using UniquePtr = std::unique_ptr< SerialExecutor, Deleter >
 

Public Member Functions

 SerialExecutor (SerialExecutor const &)=delete
 
SerialExecutoroperator= (SerialExecutor const &)=delete
 
 SerialExecutor (SerialExecutor &&)=delete
 
SerialExecutoroperator= (SerialExecutor &&)=delete
 
void add (Func func) override
 
void addWithPriority (Func func, int8_t priority) override
 
uint8_t getNumPriorities () const override
 
- Public Member Functions inherited from folly::Executor
virtual ~Executor ()
 

Static Public Member Functions

static KeepAlive< SerialExecutorcreate (KeepAlive< Executor > parent=getKeepAliveToken(getCPUExecutor().get()))
 
static UniquePtr createUnique (std::shared_ptr< Executor > parent=getCPUExecutor())
 
- 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)
 

Protected Member Functions

bool keepAliveAcquire () override
 
void keepAliveRelease () override
 

Private Member Functions

 SerialExecutor (KeepAlive< Executor > parent)
 
 ~SerialExecutor () override
 
void run ()
 

Private Attributes

KeepAlive< Executorparent_
 
std::atomic< std::size_t > scheduled_ {0}
 
folly::UnboundedQueue< Func, false, true, false > queue_
 
std::atomic< ssize_t > keepAliveCounter_ {1}
 

Additional Inherited Members

- 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
 
- 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

Executor that guarantees serial non-concurrent execution of added tasks.

SerialExecutor is similar to boost asio's strand concept. A SerialExecutor has a parent executor which is given at construction time (defaults to folly's global CPUExecutor). Tasks added to SerialExecutor are executed in the parent executor, however strictly non-concurrently and in the order they were added.

SerialExecutor tries to schedule its tasks fairly. Every task submitted to it results in one task submitted to the parent executor. Whenever the parent executor executes one of those, one of the tasks submitted to SerialExecutor is marked for execution, which means it will either be executed at once, or if a task is currently being executed already, after that.

The SerialExecutor may be deleted at any time. All tasks that have been submitted will still be executed with the same guarantees, as long as the parent executor is executing tasks.

Definition at line 52 of file SerialExecutor.h.

Member Typedef Documentation

Definition at line 78 of file SerialExecutor.h.

Constructor & Destructor Documentation

folly::SerialExecutor::SerialExecutor ( SerialExecutor const &  )
delete
folly::SerialExecutor::SerialExecutor ( SerialExecutor &&  )
delete
folly::SerialExecutor::SerialExecutor ( KeepAlive< Executor parent)
explicitprivate
folly::SerialExecutor::~SerialExecutor ( )
overrideprivate

Definition at line 28 of file SerialExecutor.cpp.

Referenced by getNumPriorities().

28  {
29  DCHECK(!keepAliveCounter_);
30 }
std::atomic< ssize_t > keepAliveCounter_

Member Function Documentation

void folly::SerialExecutor::add ( Func  func)
overridevirtual

Add one task for execution in the parent executor

Implements folly::Executor.

Definition at line 59 of file SerialExecutor.cpp.

References folly::Executor::getKeepAliveToken(), and folly::gen::move.

59  {
60  queue_.enqueue(std::move(func));
61  parent_->add([keepAlive = getKeepAliveToken(this)] { keepAlive->run(); });
62 }
constexpr detail::Map< Move > move
Definition: Base-inl.h:2567
folly::UnboundedQueue< Func, false, true, false > queue_
static KeepAlive< ExecutorT > getKeepAliveToken(ExecutorT *executor)
Definition: Executor.h:138
KeepAlive< Executor > parent_
void folly::SerialExecutor::addWithPriority ( Func  func,
int8_t  priority 
)
overridevirtual

Add one task for execution in the parent executor, and use the given priority for one task submission to parent executor.

Since in-order execution of tasks submitted to SerialExecutor is guaranteed, the priority given here does not necessarily reflect the execution priority of the task submitted with this call to addWithPriority. The given priority is passed on to the parent executor for the execution of one of the SerialExecutor's tasks.

Reimplemented from folly::Executor.

Definition at line 64 of file SerialExecutor.cpp.

References folly::Executor::getKeepAliveToken(), and folly::gen::move.

64  {
65  queue_.enqueue(std::move(func));
66  parent_->addWithPriority(
67  [keepAlive = getKeepAliveToken(this)] { keepAlive->run(); }, priority);
68 }
constexpr detail::Map< Move > move
Definition: Base-inl.h:2567
folly::UnboundedQueue< Func, false, true, false > queue_
static KeepAlive< ExecutorT > getKeepAliveToken(ExecutorT *executor)
Definition: Executor.h:138
KeepAlive< Executor > parent_
Executor::KeepAlive< SerialExecutor > folly::SerialExecutor::create ( KeepAlive< Executor parent = getKeepAliveToken(getCPUExecutor().get()))
static

Definition at line 32 of file SerialExecutor.cpp.

References folly::gen::move.

Referenced by folly::isSequencedExecutor(), and folly::TEST().

33  {
34  return makeKeepAlive<SerialExecutor>(new SerialExecutor(std::move(parent)));
35 }
constexpr detail::Map< Move > move
Definition: Base-inl.h:2567
SerialExecutor(SerialExecutor const &)=delete
folly::Function< void()> parent
Definition: AtFork.cpp:34
SerialExecutor::UniquePtr folly::SerialExecutor::createUnique ( std::shared_ptr< Executor parent = getCPUExecutor())
static

Definition at line 37 of file SerialExecutor.cpp.

References folly::pushmi::executor, folly::Executor::getKeepAliveToken(), and folly::gen::move.

38  {
40  return {executor, Deleter{std::move(parent)}};
41 }
constexpr detail::Map< Move > move
Definition: Base-inl.h:2567
PUSHMI_INLINE_VAR constexpr __adl::get_executor_fn executor
static KeepAlive< ExecutorT > getKeepAliveToken(ExecutorT *executor)
Definition: Executor.h:138
SerialExecutor(SerialExecutor const &)=delete
folly::Function< void()> parent
Definition: AtFork.cpp:34
uint8_t folly::SerialExecutor::getNumPriorities ( ) const
inlineoverridevirtual

Reimplemented from folly::Executor.

Definition at line 98 of file SerialExecutor.h.

References keepAliveAcquire(), keepAliveRelease(), parent, folly::SerialExecutor::Deleter::parent_, run(), folly::SerialExecutor::Deleter::SerialExecutor, and ~SerialExecutor().

98  {
99  return parent_->getNumPriorities();
100  }
KeepAlive< Executor > parent_
bool folly::SerialExecutor::keepAliveAcquire ( )
overrideprotectedvirtual

Reimplemented from folly::Executor.

Definition at line 43 of file SerialExecutor.cpp.

Referenced by getNumPriorities().

43  {
44  auto keepAliveCounter =
45  keepAliveCounter_.fetch_add(1, std::memory_order_relaxed);
46  DCHECK(keepAliveCounter > 0);
47  return true;
48 }
std::atomic< ssize_t > keepAliveCounter_
void folly::SerialExecutor::keepAliveRelease ( )
overrideprotectedvirtual

Reimplemented from folly::Executor.

Definition at line 50 of file SerialExecutor.cpp.

Referenced by getNumPriorities(), and folly::SerialExecutor::Deleter::operator()().

50  {
51  auto keepAliveCounter =
52  keepAliveCounter_.fetch_sub(1, std::memory_order_acq_rel);
53  DCHECK(keepAliveCounter > 0);
54  if (keepAliveCounter == 1) {
55  delete this;
56  }
57 }
std::atomic< ssize_t > keepAliveCounter_
SerialExecutor& folly::SerialExecutor::operator= ( SerialExecutor const &  )
delete
SerialExecutor& folly::SerialExecutor::operator= ( SerialExecutor &&  )
delete
void folly::SerialExecutor::run ( )
private

Definition at line 70 of file SerialExecutor.cpp.

References folly::exceptionStr().

Referenced by getNumPriorities().

70  {
71  // We want scheduled_ to guard side-effects of completed tasks, so we can't
72  // use std::memory_order_relaxed here.
73  if (scheduled_.fetch_add(1, std::memory_order_acquire) > 0) {
74  return;
75  }
76 
77  do {
78  Func func;
79  queue_.dequeue(func);
80 
81  try {
82  func();
83  } catch (std::exception const& ex) {
84  LOG(ERROR) << "SerialExecutor: func threw unhandled exception "
85  << folly::exceptionStr(ex);
86  } catch (...) {
87  LOG(ERROR) << "SerialExecutor: func threw unhandled non-exception "
88  "object";
89  }
90 
91  // We want scheduled_ to guard side-effects of completed tasks, so we can't
92  // use std::memory_order_relaxed here.
93  } while (scheduled_.fetch_sub(1, std::memory_order_release) > 1);
94 }
fbstring exceptionStr(const std::exception &e)
Function< void()> Func
Definition: Executor.h:27
folly::UnboundedQueue< Func, false, true, false > queue_
std::atomic< std::size_t > scheduled_

Member Data Documentation

std::atomic<ssize_t> folly::SerialExecutor::keepAliveCounter_ {1}
private

Definition at line 121 of file SerialExecutor.h.

KeepAlive<Executor> folly::SerialExecutor::parent_
private

Definition at line 113 of file SerialExecutor.h.

folly::UnboundedQueue<Func, false, true, false> folly::SerialExecutor::queue_
private

Unbounded multi producer single consumer queue where consumers don't block on dequeue.

Definition at line 119 of file SerialExecutor.h.

std::atomic<std::size_t> folly::SerialExecutor::scheduled_ {0}
private

Definition at line 114 of file SerialExecutor.h.


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