// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- // vim: ts=8 sw=2 smarttab /* * Ceph - scalable distributed file system * * Copyright (C) 2020 Red Hat * * This is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License version 2.1, as published by the Free Software * Foundation. See file COPYING. * */ #include #include #include #include #include "common/ceph_timer.h" using namespace std::literals; namespace { template void run_some() { static constexpr auto MAX_FUTURES = 5; ceph::timer timer; std::vector> futures; for (auto i = 0; i < MAX_FUTURES; ++i) { auto t = TC::now() + 2s; std::promise p; futures.push_back(p.get_future()); timer.add_event(t, [p = std::move(p)]() mutable { p.set_value(); }); } for (auto& f : futures) f.get(); } template void run_orderly() { ceph::timer timer; std::future first; std::future second; { std::promise p; second = p.get_future(); timer.add_event(4s, [p = std::move(p)]() mutable { p.set_value(TC::now()); }); } { std::promise p; first = p.get_future(); timer.add_event(2s, [p = std::move(p)]() mutable { p.set_value(TC::now()); }); } EXPECT_LT(first.get(), second.get()); } struct Destructo { bool armed = true; std::promise p; Destructo(std::promise&& p) : p(std::move(p)) {} Destructo(const Destructo&) = delete; Destructo& operator =(const Destructo&) = delete; Destructo(Destructo&& rhs) { p = std::move(rhs.p); armed = rhs.armed; rhs.armed = false; } Destructo& operator =(Destructo& rhs) { p = std::move(rhs.p); rhs.armed = false; armed = rhs.armed; rhs.armed = false; return *this; } ~Destructo() { if (armed) p.set_value(); } void operator ()() const { FAIL(); } }; template void cancel_all() { ceph::timer timer; static constexpr auto MAX_FUTURES = 5; std::vector> futures; for (auto i = 0; i < MAX_FUTURES; ++i) { std::promise p; futures.push_back(p.get_future()); timer.add_event(100s + i*1s, Destructo(std::move(p))); } timer.cancel_all_events(); for (auto& f : futures) f.get(); } template void cancellation() { ceph::timer timer; { std::promise p; auto f = p.get_future(); auto e = timer.add_event(100s, Destructo(std::move(p))); EXPECT_TRUE(timer.cancel_event(e)); } { std::promise p; auto f = p.get_future(); auto e = timer.add_event(1s, [p = std::move(p)]() mutable { p.set_value(); }); f.get(); EXPECT_FALSE(timer.cancel_event(e)); } } } TEST(RunSome, Steady) { run_some(); } TEST(RunSome, Wall) { run_some(); } TEST(RunOrderly, Steady) { run_orderly(); } TEST(RunOrderly, Wall) { run_orderly(); } TEST(CancelAll, Steady) { cancel_all(); } TEST(CancelAll, Wall) { cancel_all(); }