// Portable C++11 timer implementation // // See: http://codereview.stackexchange.com/questions/40473/portable-periodic-one-shot-timer-implementation // // No license given. // // Example: // // Timer t; // // Timer fires once, one second from now // t.create(1000, 0, // []() { // std::cout << "Non-periodic timer fired" << std::endl; // }); // // Timer fires every second, starting five seconds from now // t.create(5000, 1000, // []() { // std::cout << "Timer fired 0" << std::endl; // }); #ifndef TIMER_H #define TIMER_H #include <thread> #include <mutex> #include <condition_variable> #include <algorithm> #include <functional> #include <chrono> #include <unordered_map> #include <set> #include <cstdint> class Timer { public: typedef uint64_t timer_id; typedef std::function<void()> handler_type; private: std::mutex sync; typedef std::unique_lock<std::mutex> ScopedLock; std::condition_variable wakeUp; private: typedef std::chrono::steady_clock Clock; typedef std::chrono::time_point<Clock> Timestamp; typedef std::chrono::milliseconds Duration; struct Instance { Instance(timer_id id = 0) : id(id), running(false) { } template<typename Tfunction> Instance(timer_id id, Timestamp next, Duration period, Tfunction && handler) noexcept : id(id), next(next), period(period), handler(std::forward<Tfunction>(handler)), running(false) { } Instance(Instance const & r) = delete; Instance(Instance && r) noexcept : id(r.id), next(r.next), period(r.period), handler(std::move(r.handler)), running(r.running) { } Instance & operator=(Instance const & r) = delete; Instance & operator=(Instance && r) { if (this != &r) { id = r.id; next = r.next; period = r.period; handler = std::move(r.handler); running = r.running; } return *this; } timer_id id; Timestamp next; Duration period; handler_type handler; bool running; }; typedef std::unordered_map<timer_id, Instance> InstanceMap; timer_id nextId; InstanceMap active; // Comparison functor to sort the timer "queue" by Instance::next struct NextActiveComparator { bool operator()(const Instance & a, const Instance & b) const { return a.next < b.next; } }; NextActiveComparator comparator; // Queue is a set of references to Instance objects, sorted by next typedef std::reference_wrapper<Instance> QueueValue; typedef std::multiset<QueueValue, NextActiveComparator> Queue; Queue queue; // Thread and exit flag std::thread worker; bool done; void threadStart(); public: Timer(); ~Timer(); timer_id create(uint64_t when, uint64_t period, const handler_type & handler); timer_id create(uint64_t when, uint64_t period, handler_type && handler); private: timer_id createImpl(Instance && item); public: bool destroy(timer_id id); bool exists(timer_id id); }; #endif // TIMER_H
# | Change | User | Description | Committed | |
---|---|---|---|---|---|
#1 | 16236 | tjuricek |
Revise FUSE-client to call p4 reconcile intelligently. This uses the main FUSE callbacks like a loopback with a notification mechanism. After no real disk access after a short period of time (like 500ms) we'll trigger a call to p4 reconcile. The "interface" to this application is currently just a file handle: /.status - Lists "ok" if there's no errors, otherwise, outputs a list of messages |