]> gitweb.factorcode.org Git - factor.git/blob - basis/alarms/alarms.factor
Factor source files should not be executable
[factor.git] / basis / alarms / alarms.factor
1 ! Copyright (C) 2005, 2008 Slava Pestov, Doug Coleman.
2 ! See http://factorcode.org/license.txt for BSD license.
3 USING: accessors assocs boxes calendar
4 combinators.short-circuit fry heaps init kernel math.order
5 namespaces quotations threads math system ;
6 IN: alarms
7
8 TUPLE: alarm
9     { quot callable initial: [ ] }
10     { start integer }
11     interval
12     { entry box } ;
13
14 <PRIVATE
15
16 SYMBOL: alarms
17 SYMBOL: alarm-thread
18
19 : notify-alarm-thread ( -- )
20     alarm-thread get-global interrupt ;
21
22 : normalize-argument ( obj -- nanoseconds )
23     >duration duration>nanoseconds >integer ;
24
25 : <alarm> ( quot start interval -- alarm )
26     alarm new
27         swap dup [ normalize-argument ] when >>interval
28         swap dup [ normalize-argument nano-count + ] when >>start
29         swap >>quot
30         <box> >>entry ;
31
32 : register-alarm ( alarm -- )
33     [ dup start>> alarms get-global heap-push* ]
34     [ entry>> >box ] bi
35     notify-alarm-thread ;
36
37 : alarm-expired? ( alarm n -- ? )
38     [ start>> ] dip <= ;
39
40 : reschedule-alarm ( alarm -- )
41     dup interval>> nano-count + >>start register-alarm ;
42
43 : call-alarm ( alarm -- )
44     [ entry>> box> drop ]
45     [ dup interval>> [ reschedule-alarm ] [ drop ] if ]
46     [ quot>> "Alarm execution" spawn drop ] tri ;
47
48 : (trigger-alarms) ( alarms n -- )
49     over heap-empty? [
50         2drop
51     ] [
52         over heap-peek drop over alarm-expired? [
53             over heap-pop drop call-alarm (trigger-alarms)
54         ] [
55             2drop
56         ] if
57     ] if ;
58
59 : trigger-alarms ( alarms -- )
60     nano-count (trigger-alarms) ;
61
62 : next-alarm ( alarms -- nanos/f )
63     dup heap-empty? [ drop f ] [ heap-peek drop start>> ] if ;
64
65 : alarm-thread-loop ( -- )
66     alarms get-global
67     dup next-alarm sleep-until
68     trigger-alarms ;
69
70 : cancel-alarms ( alarms -- )
71     [
72         heap-pop-all [ nip entry>> box> drop ] assoc-each
73     ] when* ;
74
75 : init-alarms ( -- )
76     alarms [ cancel-alarms <min-heap> ] change-global
77     [ alarm-thread-loop t ] "Alarms" spawn-server
78     alarm-thread set-global ;
79
80 [ init-alarms ] "alarms" add-startup-hook
81
82 PRIVATE>
83
84 : add-alarm ( quot start interval -- alarm )
85     <alarm> [ register-alarm ] keep ;
86
87 : later ( quot duration -- alarm ) f add-alarm ;
88
89 : every ( quot duration -- alarm ) dup add-alarm ;
90
91 : cancel-alarm ( alarm -- )
92     entry>> [ alarms get-global heap-delete ] if-box? ;