6 "github.com/hashicorp/terraform/config"
9 // Semaphore is a wrapper around a channel to provide
10 // utility methods to clarify that we are treating the
11 // channel as a semaphore
12 type Semaphore chan struct{}
14 // NewSemaphore creates a semaphore that allows up
15 // to a given limit of simultaneous acquisitions
16 func NewSemaphore(n int) Semaphore {
18 panic("semaphore with limit 0")
20 ch := make(chan struct{}, n)
24 // Acquire is used to acquire an available slot.
25 // Blocks until available.
26 func (s Semaphore) Acquire() {
30 // TryAcquire is used to do a non-blocking acquire.
31 // Returns a bool indicating success
32 func (s Semaphore) TryAcquire() bool {
41 // Release is used to return a slot. Acquire must
42 // be called as a pre-condition.
43 func (s Semaphore) Release() {
47 panic("release without an acquire")
51 func resourceProvider(resourceType, explicitProvider string) string {
52 return config.ResourceProviderFullName(resourceType, explicitProvider)
55 // strSliceContains checks if a given string is contained in a slice
56 // When anybody asks why Go needs generics, here you go.
57 func strSliceContains(haystack []string, needle string) bool {
58 for _, s := range haystack {
66 // deduplicate a slice of strings
67 func uniqueStrings(s []string) []string {
73 result := make([]string, 1, len(s))
75 for i := 1; i < len(s); i++ {
76 if s[i] != result[len(result)-1] {
77 result = append(result, s[i])