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  }