github.com/opentofu/opentofu@v1.7.1/internal/tofu/util.go (about) 1 // Copyright (c) The OpenTofu Authors 2 // SPDX-License-Identifier: MPL-2.0 3 // Copyright (c) 2023 HashiCorp, Inc. 4 // SPDX-License-Identifier: MPL-2.0 5 6 package tofu 7 8 // Semaphore is a wrapper around a channel to provide 9 // utility methods to clarify that we are treating the 10 // channel as a semaphore 11 type Semaphore chan struct{} 12 13 // NewSemaphore creates a semaphore that allows up 14 // to a given limit of simultaneous acquisitions 15 func NewSemaphore(n int) Semaphore { 16 if n <= 0 { 17 panic("semaphore with limit <=0") 18 } 19 ch := make(chan struct{}, n) 20 return Semaphore(ch) 21 } 22 23 // Acquire is used to acquire an available slot. 24 // Blocks until available. 25 func (s Semaphore) Acquire() { 26 s <- struct{}{} 27 } 28 29 // TryAcquire is used to do a non-blocking acquire. 30 // Returns a bool indicating success 31 func (s Semaphore) TryAcquire() bool { 32 select { 33 case s <- struct{}{}: 34 return true 35 default: 36 return false 37 } 38 } 39 40 // Release is used to return a slot. Acquire must 41 // be called as a pre-condition. 42 func (s Semaphore) Release() { 43 select { 44 case <-s: 45 default: 46 panic("release without an acquire") 47 } 48 }