1 /* 2 * Kiss - A refined core library for D programming language. 3 * 4 * Copyright (C) 2015-2018 Shanghai Putao Technology Co., Ltd 5 * 6 * Developer: HuntLabs.cn 7 * 8 * Licensed under the Apache-2.0 License. 9 * 10 */ 11 12 module kiss.event.timer.epoll; 13 14 // dfmt off 15 version (linux) : 16 // dfmt on 17 18 import kiss.event.core; 19 import kiss.event.timer.common; 20 21 import core.sys.posix.unistd; 22 import core.sys.posix.time : itimerspec, CLOCK_MONOTONIC; 23 24 import core.time; 25 import std.datetime; 26 import std.exception; 27 import kiss.logger; 28 import std.socket; 29 30 /** 31 */ 32 abstract class AbstractTimer : TimerChannelBase 33 { 34 this(Selector loop) 35 { 36 super(loop); 37 init(); 38 } 39 40 private void init() 41 { 42 setFlag(WatchFlag.Read, true); 43 _readBuffer = new UintObject(); 44 this.handle = timerfd_create(CLOCK_MONOTONIC, TFD_CLOEXEC | TFD_NONBLOCK); 45 } 46 47 ~this() 48 { 49 close(); 50 } 51 52 bool setTimer() 53 { 54 itimerspec its; 55 ulong sec, nsec; 56 sec = time / 1000; 57 nsec = (time % 1000) * 1_000_000; 58 its.it_value.tv_sec = cast(typeof(its.it_value.tv_sec)) sec; 59 its.it_value.tv_nsec = cast(typeof(its.it_value.tv_nsec)) nsec; 60 its.it_interval.tv_sec = its.it_value.tv_sec; 61 its.it_interval.tv_nsec = its.it_value.tv_nsec; 62 const int err = timerfd_settime(this.handle, 0, &its, null); 63 if (err == -1) 64 { 65 return false; 66 } 67 return true; 68 } 69 70 bool readTimer(scope ReadCallBack read) 71 { 72 this.clearError(); 73 uint value; 74 core.sys.posix.unistd.read(this.handle, &value, 8); 75 this._readBuffer.data = value; 76 if (read) 77 read(this._readBuffer); 78 return false; 79 } 80 81 UintObject _readBuffer; 82 } 83 84 85 /** 86 C APIs for timerfd 87 */ 88 enum TFD_TIMER_ABSTIME = 1 << 0; 89 enum TFD_CLOEXEC = 0x80000; 90 enum TFD_NONBLOCK = 0x800; 91 92 extern (C) 93 { 94 socket_t timerfd_create(int clockid, int flags) nothrow; 95 int timerfd_settime(int fd, int flags, const itimerspec* new_value, itimerspec* old_value) nothrow; 96 int timerfd_gettime(int fd, itimerspec* curr_value) nothrow; 97 }