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

Class SemaphoreImpl

packages/effect/src/Semaphore.ts:225–322  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

223 })
224
225class SemaphoreImpl implements Semaphore {
226 public waiters = new Set<() => void>()
227 public taken = 0
228 public permits: number
229
230 constructor(permits: number) {
231 this.permits = permits
232 }
233
234 get free() {
235 return this.permits - this.taken
236 }
237
238 take(n: number): Effect.Effect<number> {
239 const take: Effect.Effect<number> = internal.suspend(() => {
240 if (this.free < n) {
241 return waitForPermits(this, n, take)
242 }
243 this.taken += n
244 return internal.succeed(n)
245 })
246 return take
247 }
248
249 takeIfAvailable(n: number): Effect.Effect<boolean> {
250 return internal.suspend(() => {
251 if (this.free < n) return internal.succeed(false)
252 this.taken += n
253 return internal.succeed(true)
254 })
255 }
256
257 releaseUnsafe(fiber: Fiber<any, any>, n: number): number {
258 this.taken -= n
259 if (this.waiters.size > 0) {
260 fiber.currentDispatcher.scheduleTask(() => {
261 for (const observer of this.waiters) {
262 if (this.free <= 0) break
263 observer()
264 }
265 }, 0)
266 }
267 return this.free
268 }
269
270 resize(permits: number) {
271 return core.withFiber((fiber) => {
272 this.permits = permits
273 if (this.free < 0) return internal.void
274 this.releaseUnsafe(fiber, 0)
275 return internal.void
276 })
277 }
278
279 release(n: number): Effect.Effect<number> {
280 return core.withFiber((fiber) => internal.succeed(this.releaseUnsafe(fiber, n)))
281 }
282

Callers

nothing calls this directly

Calls 1

withPermitsMethod · 0.95

Tested by

no test coverage detected