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 }