From 9e1e42ce7082a788b95682cbbaa4c0cec82f7b9e Mon Sep 17 00:00:00 2001 From: Hans Schallmoser <99032404+hansSchall@users.noreply.github.com> Date: Tue, 1 Apr 2025 14:51:59 +0200 Subject: [PATCH] fix: barrier resume order --- src/async/barrier.mts | 28 +++++++++++++++++----------- 1 file changed, 17 insertions(+), 11 deletions(-) diff --git a/src/async/barrier.mts b/src/async/barrier.mts index 81363b5..74025f7 100644 --- a/src/async/barrier.mts +++ b/src/async/barrier.mts @@ -5,6 +5,7 @@ The MIT License (MIT) Copyright (c) 2024 Haydn Paterson (sinclair) +Copyright (c) 2025 Hans Schallmoser (hansSchall) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal @@ -27,33 +28,38 @@ THE SOFTWARE. ---------------------------------------------------------------------------*/ export interface BarrierOptions { - paused: boolean + paused: boolean; } export class Barrier { - readonly #resolvers: Array<() => void> = [] - #paused: boolean = true + readonly #resolvers: Array<() => void> = []; + #paused: boolean = true; /** Creates a new barrier in the given state. The default is paused: true */ constructor(options: BarrierOptions) { - this.#paused = options.paused + this.#paused = options.paused; } /** Pauses this barrier causing operations to wait. */ public pause(): void { - this.#paused = true + this.#paused = true; } /** Resumes this barrier causing all operations to run. */ public resume(): void { - this.#paused = false - this.#dispatch() + this.#paused = false; + this.#dispatch(); } /** Waits until this barrier enters a resumed state. */ public wait(): Promise { - return this.#paused ? new Promise((resolve) => this.#resolvers.push(resolve)) : Promise.resolve(void 0) + return this.#paused ? new Promise((resolve) => this.#resolvers.push(resolve)) : Promise.resolve(void 0); } async #dispatch(): Promise { - while (!this.#paused && this.#resolvers.length > 0) { - const resolve = this.#resolvers.shift()! - resolve() + const next = this.#resolvers.shift(); + if (next) { + next(); + queueMicrotask(() => { + if (!this.#paused) { + this.#dispatch(); + } + }); } } }