/*
- * Copyright 2015 Facebook, Inc.
+ * Copyright 2016 Facebook, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
#include <folly/detail/Futex.h>
#include <folly/experimental/fibers/TimeoutController.h>
-namespace folly { namespace fibers {
+namespace folly {
+namespace fibers {
class Fiber;
+class FiberManager;
/**
* @class Baton
*
- * Primitive which allows to put current Fiber to sleep and wake it from another
- * Fiber/thread.
+ * Primitive which allows one to put current Fiber to sleep and wake it from
+ * another Fiber/thread.
*/
class Baton {
public:
+ class TimeoutHandler;
+
Baton();
~Baton() {}
*/
void wait();
+ /**
+ * Put active fiber to sleep indefinitely. However, timeoutHandler may
+ * be used elsewhere on the same thread in order to schedule a wakeup
+ * for the active fiber. Users of timeoutHandler must be on the same thread
+ * as the active fiber and may only schedule one timeout, which must occur
+ * after the active fiber calls wait.
+ */
+ void wait(TimeoutHandler& timeoutHandler);
+
/**
* Puts active fiber to sleep. Returns when post is called.
*
* This is here only not break tao/locks. Please don't use it, because it is
* inefficient when used on Fibers.
*/
- template<typename C, typename D = typename C::duration>
- bool timed_wait(const std::chrono::time_point<C,D>& timeout);
+ template <typename C, typename D = typename C::duration>
+ bool timed_wait(const std::chrono::time_point<C, D>& timeout);
/**
* Puts active fiber to sleep. Returns when post is called.
*/
void reset();
+ /**
+ * Provides a way to schedule a wakeup for a wait()ing fiber.
+ * A TimeoutHandler must be passed to Baton::wait(TimeoutHandler&)
+ * before a timeout is scheduled. It is only safe to use the
+ * TimeoutHandler on the same thread as the wait()ing fiber.
+ * scheduleTimeout() may only be called once prior to the end of the
+ * associated Baton's life.
+ */
+ class TimeoutHandler {
+ public:
+ void scheduleTimeout(TimeoutController::Duration timeoutMs);
+
+ private:
+ friend class Baton;
+
+ void cancelTimeout();
+
+ std::function<void()> timeoutFunc_{nullptr};
+ FiberManager* fiberManager_{nullptr};
+
+ intptr_t timeoutPtr_{0};
+ };
+
private:
enum {
/**
PreBlockAttempts = 300,
};
- explicit Baton(intptr_t state) : waitingFiber_(state) {};
+ explicit Baton(intptr_t state) : waitingFiber_(state){};
void postHelper(intptr_t new_value);
void postThread();
} futex_;
};
};
-
-}}
+}
+}
#include <folly/experimental/fibers/Baton-inl.h>