1 /*
2  * Copyright (c) 2024 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 COMMUNICATIONNETSTACK_TIMEOUT_TIMER_H
17 #define COMMUNICATIONNETSTACK_TIMEOUT_TIMER_H
18 
19 #include <sys/epoll.h>
20 #include <sys/timerfd.h>
21 
22 #include <string.h>
23 #include <unistd.h>
24 
25 #include "epoller.h"
26 #include "file_descriptor.h"
27 #include "securec.h"
28 
29 namespace OHOS::NetStack::HttpOverCurl {
30 
31 static constexpr long MILLISECONDS_IN_SECOND = 1000;
32 static constexpr long NANOSECONDS_IN_MILLISECOND = 1000 * 1000;
33 
34 struct TimeoutTimer {
TimeoutTimerTimeoutTimer35     TimeoutTimer()
36     {
37         underlying_ = timerfd_create(CLOCK_MONOTONIC, TFD_NONBLOCK | TFD_CLOEXEC);
38     }
39 
~TimeoutTimerTimeoutTimer40     ~TimeoutTimer()
41     {
42         close(underlying_);
43     }
44 
45     TimeoutTimer(const TimeoutTimer &) = delete;
46     TimeoutTimer(TimeoutTimer &&other) = default;
47 
RegisterForPollingTimeoutTimer48     void RegisterForPolling(Epoller &poller) const
49     {
50         poller.RegisterMe(underlying_);
51     }
52 
IsItYoursTimeoutTimer53     [[nodiscard]] bool IsItYours(FileDescriptor descriptor) const
54     {
55         return descriptor == underlying_;
56     }
57 
StopTimeoutTimer58     void Stop()
59     {
60         SetTimeoutMs(0);
61     }
62 
SetTimeoutNsTimeoutTimer63     void SetTimeoutNs(long timeoutNs)
64     {
65         itimerspec its{};
66         memset_s(&its, sizeof(itimerspec), 0, sizeof(itimerspec));
67 
68         if (timeoutNs > 0) {
69             its.it_value.tv_nsec = timeoutNs;
70         }
71 
72         timerfd_settime(underlying_, 0, &its, nullptr);
73     }
74 
SetTimeoutMsTimeoutTimer75     void SetTimeoutMs(long timeoutMs)
76     {
77         itimerspec its{};
78         memset_s(&its, sizeof(itimerspec), 0, sizeof(itimerspec));
79 
80         if (timeoutMs > 0) {
81             its.it_value.tv_sec = timeoutMs / MILLISECONDS_IN_SECOND;
82             its.it_value.tv_nsec = (timeoutMs % MILLISECONDS_IN_SECOND) * NANOSECONDS_IN_MILLISECOND;
83         }
84 
85         timerfd_settime(underlying_, 0, &its, nullptr);
86     }
87 
ResetEventTimeoutTimer88     void ResetEvent()
89     {
90         uint64_t count = 0;
91         read(underlying_, &count, sizeof(uint64_t));
92     }
93 
94 private:
95     FileDescriptor underlying_;
96 };
97 
98 } // namespace OHOS::NetStack::HttpOverCurl
99 
100 #endif // COMMUNICATIONNETSTACK_TIMEOUT_TIMER_H
101