1 /* 2 * Copyright (c) 2021 Huawei Device Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 16 #ifndef UTILS_TIMER_H 17 #define UTILS_TIMER_H 18 19 #include <sys/types.h> 20 #include <cstdint> 21 #include <string> 22 #include <list> 23 #include <map> 24 #include <mutex> 25 #include <thread> 26 #include <vector> 27 28 #include "../src/event_reactor.h" 29 30 namespace OHOS { 31 namespace Utils { 32 33 class Timer { 34 public: 35 using TimerCallback = std::function<void ()>; 36 using TimerCallbackPtr = std::shared_ptr<TimerCallback>; 37 using TimerListCallback = std::function<void (int timerFd)>; 38 39 public: 40 /* 41 * if performance-sensitive, change "timeout" larger before Setup 42 * default-value(1000ms), performance-estimate: occupy fixed-100us in every default-value(1000ms) 43 * timeout: range [-1, INT32MAX], but [-1,0] is not recommended 44 * -1: wait for ever(until event-trigger); 45 * 0: no wait, occupy too much cpu time; 46 * others: wait(until event-trigger) 47 */ 48 explicit Timer(const std::string& name, int timeoutMs = 1000); ~Timer()49 virtual ~Timer(){} 50 51 virtual uint32_t Setup(); 52 53 /* 54 * useJoin true: use std::thread::join(default) 55 * false: use std::thread::detach(not recommended) 56 * if timeoutMs = -1 and no valid event-trigger in epoll_wait: 57 * use std::thread::detach inside to avoid deadloop 58 */ 59 virtual void Shutdown(bool useJoin = true); 60 61 uint32_t Register(const TimerCallback& callback, uint32_t interval /* ms */, bool once = false); 62 void Unregister(uint32_t timerId); 63 64 private: 65 void MainLoop(); 66 void OnTimer(int timerFd); 67 virtual uint32_t DoRegister(const TimerListCallback& callback, uint32_t interval, bool once, int &timerFd); 68 virtual void DoUnregister(uint32_t interval); 69 void DoTimerListCallback(const TimerListCallback& callback, int timerFd); 70 uint32_t GetValidId(uint32_t timerId) const; 71 int GetTimerFd(uint32_t interval /* ms */); 72 void EraseUnusedTimerId(uint32_t interval, const std::vector<uint32_t>& unusedIds); 73 74 private: 75 struct TimerEntry { 76 uint32_t timerId; // unique id 77 uint32_t interval; // million second 78 TimerCallback callback; 79 bool once; 80 int timerFd; 81 }; 82 83 using TimerEntryPtr = std::shared_ptr<TimerEntry>; 84 using TimerEntryList = std::list<TimerEntryPtr>; 85 86 std::map<uint32_t, TimerEntryList> intervalToTimers_; // interval to TimerEntryList 87 std::map<uint32_t, TimerEntryPtr> timerToEntries_; // timer_id to TimerEntry 88 89 std::string name_; 90 int timeoutMs_; 91 std::thread thread_; 92 std::unique_ptr<EventReactor> reactor_; 93 std::map<uint32_t, uint32_t> timers_; // timer_fd to interval 94 std::mutex mutex_; 95 }; 96 97 } // namespace Utils 98 } // namespace OHOS 99 #endif 100 101