namespace folly { namespace wangle {
+/// This generic threadgate takes two executors and an optional waiter (if you
+/// need to support waiting). Hint: use executors that inherit from Executor
+/// (in Executor.h), then you just do
+///
+/// GenericThreadGate tg(westExecutor, eastExecutor, waiter);
template <
class WestExecutorPtr = Executor*,
class EastExecutorPtr = Executor*,
WestExecutorPtr westExecutor;
EastExecutorPtr eastExecutor;
WaiterPtr waiter;
+
private:
void makeProgress_(std::true_type const&) {
throw std::logic_error("No waiter.");
/*
* Resets the executor - all then() calls made after the call to via() will be
- * made in the new executor.
+ * made in the new executor. The Executor must outlive.
*/
Later<T> via(Executor* executor);
/*
* Starts the workflow. The function provided in the constructor will be
- * called in the executor provided in the constructor. All proximate then()
+ * called in the executor provided in the constructor. Subsequent then()
* calls will be made, potentially changing threads if a via() call is made.
* The future returned will be fulfilled in the last executor.
*
* Thread safety issues of Futures still apply. If you want to wait on the
- * Future, it must be done in the thread that will fulfill it. If you do not
+ * Future, it must be done in the thread that will fulfil it. If you do not
* plan to use the result of the Future, use fireAndForget()
*/
Future<T> launch();
In order to make and use a ThreadGate, you need to provide a strategy for
executing code in the east and west threads. These strategies may be
different. The only requirement is a threadsafe method
- `void add(function<void()>&&)`. You may find the executors in
- Executor.h handy, but ensure that you are using them
- threadsafely.
+ `void add(function<void()>&&)`.
In order for your ThreadGate to do anything, you need to drive those
executors somehow. An event loop is a natural fit. A thread pool might be
Future change toward a multithreaded architecture easier, as you need only
change the components of the ThreadGate which your client code is already
using.
+
+ Later (in Later.h) is an alternative mechanism for thread-traversing
+ asynchronous workflows.
*/
class ThreadGate {
public:
In summary, both east and west need to have plans to drive their
executors, or nothing will actually happen. When the executors are driven,
- then everything flows. */
+ then everything flows. */
template <class T>
Future<T> gate(std::function<Future<T>()>&& fn) {
Promise<T> pWest;