11e934351Sopenharmony_ci/*
21e934351Sopenharmony_ci * Copyright (c) 2024 Huawei Device Co., Ltd.
31e934351Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
41e934351Sopenharmony_ci * you may not use this file except in compliance with the License.
51e934351Sopenharmony_ci * You may obtain a copy of the License at
61e934351Sopenharmony_ci *
71e934351Sopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
81e934351Sopenharmony_ci *
91e934351Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software
101e934351Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
111e934351Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
121e934351Sopenharmony_ci * See the License for the specific language governing permissions and
131e934351Sopenharmony_ci * limitations under the License.
141e934351Sopenharmony_ci */
151e934351Sopenharmony_ci
161e934351Sopenharmony_ci#ifndef COMMUNICATIONNETSTACK_TIMEOUT_TIMER_H
171e934351Sopenharmony_ci#define COMMUNICATIONNETSTACK_TIMEOUT_TIMER_H
181e934351Sopenharmony_ci
191e934351Sopenharmony_ci#include <sys/epoll.h>
201e934351Sopenharmony_ci#include <sys/timerfd.h>
211e934351Sopenharmony_ci
221e934351Sopenharmony_ci#include <string.h>
231e934351Sopenharmony_ci#include <unistd.h>
241e934351Sopenharmony_ci
251e934351Sopenharmony_ci#include "epoller.h"
261e934351Sopenharmony_ci#include "file_descriptor.h"
271e934351Sopenharmony_ci#include "securec.h"
281e934351Sopenharmony_ci
291e934351Sopenharmony_cinamespace OHOS::NetStack::HttpOverCurl {
301e934351Sopenharmony_ci
311e934351Sopenharmony_cistatic constexpr long MILLISECONDS_IN_SECOND = 1000;
321e934351Sopenharmony_cistatic constexpr long NANOSECONDS_IN_MILLISECOND = 1000 * 1000;
331e934351Sopenharmony_ci
341e934351Sopenharmony_cistruct TimeoutTimer {
351e934351Sopenharmony_ci    TimeoutTimer()
361e934351Sopenharmony_ci    {
371e934351Sopenharmony_ci        underlying_ = timerfd_create(CLOCK_MONOTONIC, TFD_NONBLOCK | TFD_CLOEXEC);
381e934351Sopenharmony_ci    }
391e934351Sopenharmony_ci
401e934351Sopenharmony_ci    ~TimeoutTimer()
411e934351Sopenharmony_ci    {
421e934351Sopenharmony_ci        close(underlying_);
431e934351Sopenharmony_ci    }
441e934351Sopenharmony_ci
451e934351Sopenharmony_ci    TimeoutTimer(const TimeoutTimer &) = delete;
461e934351Sopenharmony_ci    TimeoutTimer(TimeoutTimer &&other) = default;
471e934351Sopenharmony_ci
481e934351Sopenharmony_ci    void RegisterForPolling(Epoller &poller) const
491e934351Sopenharmony_ci    {
501e934351Sopenharmony_ci        poller.RegisterMe(underlying_);
511e934351Sopenharmony_ci    }
521e934351Sopenharmony_ci
531e934351Sopenharmony_ci    [[nodiscard]] bool IsItYours(FileDescriptor descriptor) const
541e934351Sopenharmony_ci    {
551e934351Sopenharmony_ci        return descriptor == underlying_;
561e934351Sopenharmony_ci    }
571e934351Sopenharmony_ci
581e934351Sopenharmony_ci    void Stop()
591e934351Sopenharmony_ci    {
601e934351Sopenharmony_ci        SetTimeoutMs(0);
611e934351Sopenharmony_ci    }
621e934351Sopenharmony_ci
631e934351Sopenharmony_ci    void SetTimeoutNs(long timeoutNs)
641e934351Sopenharmony_ci    {
651e934351Sopenharmony_ci        itimerspec its{};
661e934351Sopenharmony_ci        memset_s(&its, sizeof(itimerspec), 0, sizeof(itimerspec));
671e934351Sopenharmony_ci
681e934351Sopenharmony_ci        if (timeoutNs > 0) {
691e934351Sopenharmony_ci            its.it_value.tv_nsec = timeoutNs;
701e934351Sopenharmony_ci        }
711e934351Sopenharmony_ci
721e934351Sopenharmony_ci        timerfd_settime(underlying_, 0, &its, nullptr);
731e934351Sopenharmony_ci    }
741e934351Sopenharmony_ci
751e934351Sopenharmony_ci    void SetTimeoutMs(long timeoutMs)
761e934351Sopenharmony_ci    {
771e934351Sopenharmony_ci        itimerspec its{};
781e934351Sopenharmony_ci        memset_s(&its, sizeof(itimerspec), 0, sizeof(itimerspec));
791e934351Sopenharmony_ci
801e934351Sopenharmony_ci        if (timeoutMs > 0) {
811e934351Sopenharmony_ci            its.it_value.tv_sec = timeoutMs / MILLISECONDS_IN_SECOND;
821e934351Sopenharmony_ci            its.it_value.tv_nsec = (timeoutMs % MILLISECONDS_IN_SECOND) * NANOSECONDS_IN_MILLISECOND;
831e934351Sopenharmony_ci        }
841e934351Sopenharmony_ci
851e934351Sopenharmony_ci        timerfd_settime(underlying_, 0, &its, nullptr);
861e934351Sopenharmony_ci    }
871e934351Sopenharmony_ci
881e934351Sopenharmony_ci    void ResetEvent()
891e934351Sopenharmony_ci    {
901e934351Sopenharmony_ci        uint64_t count = 0;
911e934351Sopenharmony_ci        read(underlying_, &count, sizeof(uint64_t));
921e934351Sopenharmony_ci    }
931e934351Sopenharmony_ci
941e934351Sopenharmony_ciprivate:
951e934351Sopenharmony_ci    FileDescriptor underlying_;
961e934351Sopenharmony_ci};
971e934351Sopenharmony_ci
981e934351Sopenharmony_ci} // namespace OHOS::NetStack::HttpOverCurl
991e934351Sopenharmony_ci
1001e934351Sopenharmony_ci#endif // COMMUNICATIONNETSTACK_TIMEOUT_TIMER_H
101