93 lines
2.0 KiB
D
93 lines
2.0 KiB
D
module jtk.timer;
|
|
|
|
import jtk.time;
|
|
import std.algorithm;
|
|
import core.sync.mutex;
|
|
|
|
private extern(C) void jtk_wake();
|
|
|
|
class Timer
|
|
{
|
|
private static __gshared Timer[Timer] timers;
|
|
private static __gshared Mutex timers_mutex;
|
|
|
|
private ulong next;
|
|
|
|
private ulong interval;
|
|
|
|
void * user;
|
|
|
|
this(ulong delay, ulong interval, void * user)
|
|
{
|
|
ulong current_time = us_time();
|
|
this.next = current_time + (delay * 1000u);
|
|
this.interval = interval * 1000u;
|
|
this.user = user;
|
|
timers_mutex.lock_nothrow();
|
|
timers[this] = this;
|
|
timers_mutex.unlock_nothrow();
|
|
/* Wake the wait loop in case this timer will expire before the
|
|
* previously calculated timeout. */
|
|
jtk_wake();
|
|
}
|
|
|
|
void remove()
|
|
{
|
|
timers_mutex.lock_nothrow();
|
|
timers.remove(this);
|
|
timers_mutex.unlock_nothrow();
|
|
}
|
|
|
|
package void service()
|
|
{
|
|
if (this.interval == 0u)
|
|
{
|
|
remove();
|
|
}
|
|
else
|
|
{
|
|
this.next += this.interval;
|
|
}
|
|
}
|
|
|
|
package static Timer get_expired_timer()
|
|
{
|
|
ulong current_time = us_time();
|
|
Timer expired_timer = null;
|
|
timers_mutex.lock_nothrow();
|
|
foreach (Timer timer; timers)
|
|
{
|
|
if (timer.next <= current_time)
|
|
{
|
|
expired_timer = timer;
|
|
break;
|
|
}
|
|
}
|
|
timers_mutex.unlock_nothrow();
|
|
return expired_timer;
|
|
}
|
|
|
|
package static ulong time_to_next_timer_expiration()
|
|
{
|
|
ulong rv = cast(ulong)-1;
|
|
ulong current_time = us_time();
|
|
timers_mutex.lock_nothrow();
|
|
foreach (Timer timer; timers)
|
|
{
|
|
if (timer.next <= current_time)
|
|
{
|
|
rv = 0u;
|
|
break;
|
|
}
|
|
rv = min(rv, timer.next - current_time);
|
|
}
|
|
timers_mutex.unlock_nothrow();
|
|
return rv;
|
|
}
|
|
|
|
package static void timer_init()
|
|
{
|
|
timers_mutex = new Mutex;
|
|
}
|
|
}
|