Skip to content

Commit 988a699

Browse files
committed
Fix clock start logic.
1 parent f270140 commit 988a699

File tree

3 files changed

+34
-11
lines changed

3 files changed

+34
-11
lines changed

src/core/clock.ml

+28-11
Original file line numberDiff line numberDiff line change
@@ -205,6 +205,7 @@ let _sync ?(pending = false) x =
205205

206206
let sync c = _sync (Unifier.deref c)
207207
let cleanup_source s = try s#force_sleep with _ -> ()
208+
let pending_clocks = WeakQueue.create ()
208209
let clocks = Queue.create ()
209210

210211
let rec _cleanup ~clock { outputs; passive_sources; active_sources } =
@@ -425,8 +426,7 @@ and _tick ~clock x =
425426
Atomic.incr x.ticks;
426427
check_stopped ();
427428
_after_tick ~clock x;
428-
check_stopped ();
429-
Queue.iter clocks start
429+
check_stopped ()
430430

431431
and _clock_thread ~clock x =
432432
let has_sources_to_process () =
@@ -516,13 +516,29 @@ and start ?force c =
516516
| `True sync -> _start ?force ~sync clock
517517
| `False -> ()
518518

519+
let add_pending_clock =
520+
(* Make sure that we're not collecting clocks between
521+
the time they have sources attached to them and before
522+
we get a chance to call [start_pending]. *)
523+
let finalise c =
524+
let clock = Unifier.deref c in
525+
match _can_start clock with
526+
| `True sync when sync <> `Passive ->
527+
_start ~sync clock;
528+
Queue.push clocks c
529+
| _ -> ()
530+
in
531+
fun c ->
532+
Gc.finalise finalise c;
533+
WeakQueue.push pending_clocks c
534+
519535
let create ?(stack = []) ?on_error ?id ?(sub_ids = []) ?(sync = `Automatic) () =
520536
let on_error_queue = Queue.create () in
521537
(match on_error with None -> () | Some fn -> Queue.push on_error_queue fn);
522538
let c =
523539
Unifier.make
524540
{
525-
id = Unifier.make (Option.map Lang_string.generate_id id);
541+
id = Unifier.make id;
526542
sub_ids;
527543
stack = Atomic.make stack;
528544
pending_activations = Queue.create ();
@@ -531,7 +547,7 @@ let create ?(stack = []) ?on_error ?id ?(sub_ids = []) ?(sync = `Automatic) () =
531547
on_error = on_error_queue;
532548
}
533549
in
534-
if sync <> `Passive then Queue.push clocks c;
550+
if sync <> `Passive then add_pending_clock c;
535551
c
536552

537553
let time c =
@@ -540,18 +556,19 @@ let time c =
540556
Time.to_float (_time c)
541557

542558
let start_pending () =
543-
let c = Queue.flush_elements clocks in
559+
let c = WeakQueue.flush_elements pending_clocks in
544560
let c = List.map (fun c -> (c, Unifier.deref c)) c in
545561
let c = List.sort_uniq (fun (_, c) (_, c') -> Stdlib.compare c c') c in
546562
List.iter
547563
(fun (c, clock) ->
548-
(match Atomic.get clock.state with
564+
match Atomic.get clock.state with
549565
| `Stopped _ -> (
550566
match _can_start clock with
551-
| `True sync -> _start ~sync clock
552-
| `False -> ())
553-
| _ -> ());
554-
Queue.push clocks c)
567+
| `True sync ->
568+
_start ~sync clock;
569+
Queue.push clocks c
570+
| `False -> WeakQueue.push pending_clocks c)
571+
| _ -> ())
555572
c
556573

557574
let () =
@@ -598,4 +615,4 @@ let create ?stack ?on_error ?id ?sync () = create ?stack ?on_error ?id ?sync ()
598615
let clocks () =
599616
List.sort_uniq
600617
(fun c c' -> Stdlib.compare (Unifier.deref c) (Unifier.deref c'))
601-
(Queue.elements clocks)
618+
(WeakQueue.elements pending_clocks @ Queue.elements clocks)

src/core/tools/queues.ml

+5
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,11 @@ module WeakQueue = struct
8080
match Weak.get x i with Some v -> fn v | None -> ()
8181
done)
8282

83+
let flush_elements q =
84+
let elements = ref [] in
85+
flush_iter q (fun el -> elements := el :: !elements);
86+
List.rev !elements
87+
8388
let elements q =
8489
let rec elements_f rem =
8590
match Queue.pop_opt q with

src/core/tools/queues.mli

+1
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ module WeakQueue : sig
5757
val create : unit -> 'a t
5858
val push : 'a t -> 'a -> unit
5959
val flush_iter : 'a t -> ('a -> unit) -> unit
60+
val flush_elements : 'a t -> 'a list
6061
val elements : 'a t -> 'a list
6162
val exists : 'a t -> ('a -> bool) -> bool
6263
val iter : 'a t -> ('a -> unit) -> unit

0 commit comments

Comments
 (0)