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