github.com/adamar/terraform@v0.2.2-0.20141016210445-2e703afdad0e/terraform/util.go (about)

     1  package terraform
     2  
     3  // Semaphore is a wrapper around a channel to provide
     4  // utility methods to clarify that we are treating the
     5  // channel as a semaphore
     6  type Semaphore chan struct{}
     7  
     8  // NewSemaphore creates a semaphore that allows up
     9  // to a given limit of simultaneous acquisitions
    10  func NewSemaphore(n int) Semaphore {
    11  	if n == 0 {
    12  		panic("semaphore with limit 0")
    13  	}
    14  	ch := make(chan struct{}, n)
    15  	return Semaphore(ch)
    16  }
    17  
    18  // Acquire is used to acquire an available slot.
    19  // Blocks until available.
    20  func (s Semaphore) Acquire() {
    21  	s <- struct{}{}
    22  }
    23  
    24  // TryAcquire is used to do a non-blocking acquire.
    25  // Returns a bool indicating success
    26  func (s Semaphore) TryAcquire() bool {
    27  	select {
    28  	case s <- struct{}{}:
    29  		return true
    30  	default:
    31  		return false
    32  	}
    33  }
    34  
    35  // Release is used to return a slot. Acquire must
    36  // be called as a pre-condition.
    37  func (s Semaphore) Release() {
    38  	select {
    39  	case <-s:
    40  	default:
    41  		panic("release without an acquire")
    42  	}
    43  }
    44  
    45  // strSliceContains checks if a given string is contained in a slice
    46  // When anybody asks why Go needs generics, here you go.
    47  func strSliceContains(haystack []string, needle string) bool {
    48  	for _, s := range haystack {
    49  		if s == needle {
    50  			return true
    51  		}
    52  	}
    53  	return false
    54  }