MCPcopy Create free account
hub / github.com/Effect-TS/effect / Latch

Class Latch

packages/effect/src/internal/effect.ts:5523–5606  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

5521const succeedFalse = succeed(false)
5522
5523class Latch implements _Latch.Latch {
5524 waiters: Array<(_: Effect.Effect<void>) => void> = []
5525 scheduled: Array<(_: Effect.Effect<void>) => void> | undefined = undefined
5526 private _isOpen: boolean
5527
5528 constructor(isOpen: boolean) {
5529 this._isOpen = isOpen
5530 }
5531
5532 private scheduleUnsafe(fiber: Fiber.Fiber<unknown, unknown>) {
5533 if (this.waiters.length === 0) {
5534 return succeedTrue
5535 }
5536 if (this.scheduled === undefined) {
5537 this.scheduled = this.waiters
5538 fiber.currentDispatcher.scheduleTask(this.flushScheduled, 0)
5539 } else {
5540 for (let i = 0; i < this.waiters.length; i++) {
5541 this.scheduled.push(this.waiters[i])
5542 }
5543 }
5544 this.waiters = []
5545 return succeedTrue
5546 }
5547 private flushScheduled = () => {
5548 if (this.scheduled === undefined) return
5549 const waiters = this.scheduled
5550 this.scheduled = undefined
5551 for (let i = 0; i < waiters.length; i++) {
5552 waiters[i](exitVoid)
5553 }
5554 }
5555 private flushWaiters() {
5556 // swap both arrays out before any resume runs: a resumed waiter can
5557 // reentrantly close the latch and register new waiters, which must not
5558 // be drained by this flush
5559 const waiters = this.waiters
5560 this.waiters = []
5561 this.flushScheduled()
5562 for (let i = 0; i < waiters.length; i++) {
5563 waiters[i](exitVoid)
5564 }
5565 }
5566
5567 open = withFiber<boolean>((fiber) => {
5568 if (this._isOpen) return succeedFalse
5569 this._isOpen = true
5570 return this.scheduleUnsafe(fiber)
5571 })
5572 release = withFiber<boolean>((fiber) => this._isOpen ? succeedFalse : this.scheduleUnsafe(fiber))
5573 openUnsafe() {
5574 if (this._isOpen) return false
5575 this._isOpen = true
5576 this.flushWaiters()
5577 return true
5578 }
5579 await = callback<void>((resume) => {
5580 if (this._isOpen) {

Callers

nothing calls this directly

Calls 6

scheduleUnsafeMethod · 0.95
closeUnsafeMethod · 0.95
pushMethod · 0.80
callbackFunction · 0.70
resumeFunction · 0.50
syncFunction · 0.50

Tested by

no test coverage detected