commit
8d7c7bc03d
@ -0,0 +1,5 @@
|
|||||||
|
;;;; package.lisp
|
||||||
|
|
||||||
|
(defpackage #:timedset
|
||||||
|
(:use #:cl
|
||||||
|
#:flan-utils))
|
@ -0,0 +1,11 @@
|
|||||||
|
;;;; timedset.asd
|
||||||
|
|
||||||
|
(asdf:defsystem #:timedset
|
||||||
|
:description "Timed running"
|
||||||
|
:author "Rin <flanchan@cumallover.me>"
|
||||||
|
:license "Public domain"
|
||||||
|
:version "0.0.1"
|
||||||
|
:serial t
|
||||||
|
:depends-on ( #:flan-utils )
|
||||||
|
:components ((:file "package")
|
||||||
|
(:file "timedset")))
|
@ -0,0 +1,81 @@
|
|||||||
|
;;;; timedset.lisp
|
||||||
|
|
||||||
|
(in-package #:timedset)
|
||||||
|
|
||||||
|
(enable-all-readers)
|
||||||
|
|
||||||
|
[ ;; exports
|
||||||
|
|
||||||
|
(defparameter *active-timers* nil)
|
||||||
|
(defparameter *lock* (bt:make-lock))
|
||||||
|
|
||||||
|
(defun at (itsu nani &optional motto)
|
||||||
|
"Run a function at specified universal-time"
|
||||||
|
(bt:with-lock-held (*lock*)
|
||||||
|
(let* ((start-time (get-universal-time))
|
||||||
|
(wait-time (- itsu start-time))
|
||||||
|
(uid (gensym)))
|
||||||
|
(if (< wait-time 0) nil
|
||||||
|
(car (push $(yield-return
|
||||||
|
(push-handler 'time-elapsed
|
||||||
|
£(- (get-universal-time) start-time))
|
||||||
|
(push-handler 'uid
|
||||||
|
£uid)
|
||||||
|
(push-handler 'data
|
||||||
|
£motto)
|
||||||
|
(sleep wait-time)
|
||||||
|
(yield (handler-case (values (funcall nani) nil)
|
||||||
|
(error (x)
|
||||||
|
(values nil x))))
|
||||||
|
(bt:with-lock-held (*lock*)
|
||||||
|
(setf *active-timers*
|
||||||
|
(where
|
||||||
|
#'(lambda (timer)
|
||||||
|
¬(eql uid (funcall (async-info-handler timer 'uid))))
|
||||||
|
*active-timers*))))
|
||||||
|
*active-timers*))))))
|
||||||
|
|
||||||
|
(defun elapsed (handle)
|
||||||
|
"Time (seconds) since timer was set"
|
||||||
|
(funcall (async-info-handler handle 'time-elapsed)))
|
||||||
|
|
||||||
|
(defun id (handle)
|
||||||
|
(funcall (async-info-handler handle 'uid)))
|
||||||
|
|
||||||
|
(defun data (handle)
|
||||||
|
(funcall (async-info-handler handle 'data)))
|
||||||
|
|
||||||
|
(defun current-active-timers ()
|
||||||
|
"Get current active timers"
|
||||||
|
(bt:with-lock-held (*lock*)
|
||||||
|
(copy-list *active-timers*)))
|
||||||
|
|
||||||
|
(defun wait-all (&optional timeout)
|
||||||
|
"Wait for all timers, optionally on timeout"
|
||||||
|
(let ((waiter
|
||||||
|
$(let ((actives nil))
|
||||||
|
(bt:with-lock-held (*lock*)
|
||||||
|
(setf actives (copy-list *active-timers*)))
|
||||||
|
(mapc #'(lambda (x)
|
||||||
|
(wait x))
|
||||||
|
actives))))
|
||||||
|
(if timeout
|
||||||
|
(progn
|
||||||
|
(sleep timeout)
|
||||||
|
(when (aync-alive waiter)
|
||||||
|
(async-kill waiter)
|
||||||
|
nil)
|
||||||
|
t)
|
||||||
|
(progn
|
||||||
|
(wait waiter)
|
||||||
|
t))))
|
||||||
|
|
||||||
|
(defun stop-all ()
|
||||||
|
"Kill all timer threads"
|
||||||
|
(bt:with-lock-held (*lock*)
|
||||||
|
(mapc #'async-kill *active-timers*)
|
||||||
|
(setf *active-timers* nil)))
|
||||||
|
|
||||||
|
] ;; end exports
|
||||||
|
|
||||||
|
(disable-all-readers)
|
Loading…
Reference in new issue