#include <limits>
#include <type_traits>
-#include <boost/noncopyable.hpp>
-
#include <folly/portability/Unistd.h>
namespace folly { namespace detail {
enum class FutexResult {
- VALUE_CHANGED, /* Futex value didn't match expected */
- AWOKEN, /* futex wait matched with a futex wake */
- INTERRUPTED, /* Spurious wake-up or signal caused futex wait failure */
- TIMEDOUT,
+ VALUE_CHANGED, /* futex value didn't match expected */
+ AWOKEN, /* wakeup by matching futex wake, or spurious wakeup */
+ INTERRUPTED, /* wakeup by interrupting signal */
+ TIMEDOUT, /* wakeup by expiring deadline */
};
/**
* (and benchmarks to back you up).
*/
template <template <typename> class Atom = std::atomic>
-struct Futex : Atom<uint32_t>, boost::noncopyable {
-
- explicit constexpr Futex(uint32_t init = 0) : Atom<uint32_t>(init) {}
+struct Futex : Atom<uint32_t> {
+ using Atom<uint32_t>::Atom;
/** Puts the thread to sleep if this->load() == expected. Returns true when
* it is returning because it has consumed a wake() event, false for any
std::chrono::steady_clock,
std::chrono::system_clock>::type;
auto const converted = time_point_conv<Target>(deadline);
- return futexWaitImpl(expected, converted, waitMask);
+ return converted == Target::time_point::max()
+ ? futexWaitImpl(expected, nullptr, nullptr, waitMask)
+ : futexWaitImpl(expected, converted, waitMask);
}
/** Wakens up to count waiters where (waitMask & wakeMask) !=
static typename TargetClock::time_point time_point_conv(
std::chrono::time_point<Clock, Duration> const& time) {
using std::chrono::duration_cast;
+ using TimePoint = std::chrono::time_point<Clock, Duration>;
using TargetDuration = typename TargetClock::duration;
using TargetTimePoint = typename TargetClock::time_point;
- if (std::is_same<Clock, TargetClock>::value) {
+ if (time == TimePoint::max()) {
+ return TargetTimePoint::max();
+ } else if (std::is_same<Clock, TargetClock>::value) {
// in place of time_point_cast, which cannot compile without if-constexpr
auto const delta = time.time_since_epoch();
return TargetTimePoint(duration_cast<TargetDuration>(delta));