1 /* 2 * Geario - A cross-platform abstraction library with asynchronous I/O. 3 * 4 * Copyright (C) 2021-2022 Kerisy.com 5 * 6 * Website: https://www.kerisy.com 7 * 8 * Licensed under the Apache-2.0 License. 9 * 10 */ 11 12 module geario.event.timer.Epoll; 13 14 // dfmt off 15 version (HAVE_EPOLL) : 16 // dfmt on 17 18 import geario.event.selector.Selector; 19 import geario.event.timer.Common; 20 import geario.Functions; 21 import geario.net.channel.Types; 22 23 import core.sys.posix.unistd; 24 import core.sys.posix.time : itimerspec, CLOCK_MONOTONIC; 25 26 import core.time; 27 import std.socket; 28 29 /** 30 */ 31 abstract class AbstractTimer : TimerChannelBase { 32 this(Selector loop) { 33 super(loop); 34 init(); 35 } 36 37 private void init() { 38 setFlag(ChannelFlag.Read, true); 39 _readBuffer = new UintObject(); 40 this.handle = timerfd_create(CLOCK_MONOTONIC, TFD_CLOEXEC | TFD_NONBLOCK); 41 // setTimer(); 42 } 43 44 ~this() @nogc { 45 // Close(); 46 } 47 48 private bool setTimer() { 49 itimerspec its; 50 ulong sec, nsec; 51 sec = time() / 1000; 52 nsec = (time() % 1000) * 1_000_000; 53 54 its.it_value.tv_sec = cast(typeof(its.it_value.tv_sec)) sec; 55 its.it_value.tv_nsec = cast(typeof(its.it_value.tv_nsec)) nsec; 56 its.it_interval.tv_sec = its.it_value.tv_sec; 57 its.it_interval.tv_nsec = its.it_value.tv_nsec; 58 const int err = timerfd_settime(this.handle, 0, &its, null); 59 if (err == -1) { 60 return false; 61 } 62 return true; 63 } 64 65 bool readTimer(scope SimpleActionHandler read) { 66 this.ClearError(); 67 uint value; 68 core.sys.posix.unistd.read(this.handle, &value, 8); 69 this._readBuffer.data = value; 70 if (read) 71 read(this._readBuffer); 72 return false; 73 } 74 75 override void Start(bool immediately = false, bool once = false) { 76 setTimer(); 77 super.Start(); 78 } 79 80 UintObject _readBuffer; 81 } 82 83 /** 84 C APIs for timerfd 85 */ 86 enum TFD_TIMER_ABSTIME = 1 << 0; 87 enum TFD_CLOEXEC = 0x80000; 88 enum TFD_NONBLOCK = 0x800; 89 90 extern (C) { 91 socket_t timerfd_create(int clockid, int flags) nothrow; 92 int timerfd_settime(int fd, int flags, const itimerspec* new_value, itimerspec* old_value) nothrow; 93 int timerfd_gettime(int fd, itimerspec* curr_value) nothrow; 94 }