]>
Commit | Line | Data |
---|---|---|
bae9f6d2 JC |
1 | package terraform |
2 | ||
3 | import ( | |
4 | "sort" | |
c680a8e1 RS |
5 | |
6 | "github.com/hashicorp/terraform/config" | |
bae9f6d2 JC |
7 | ) |
8 | ||
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{} | |
13 | ||
14 | // NewSemaphore creates a semaphore that allows up | |
15 | // to a given limit of simultaneous acquisitions | |
16 | func NewSemaphore(n int) Semaphore { | |
17 | if n == 0 { | |
18 | panic("semaphore with limit 0") | |
19 | } | |
20 | ch := make(chan struct{}, n) | |
21 | return Semaphore(ch) | |
22 | } | |
23 | ||
24 | // Acquire is used to acquire an available slot. | |
25 | // Blocks until available. | |
26 | func (s Semaphore) Acquire() { | |
27 | s <- struct{}{} | |
28 | } | |
29 | ||
30 | // TryAcquire is used to do a non-blocking acquire. | |
31 | // Returns a bool indicating success | |
32 | func (s Semaphore) TryAcquire() bool { | |
33 | select { | |
34 | case s <- struct{}{}: | |
35 | return true | |
36 | default: | |
37 | return false | |
38 | } | |
39 | } | |
40 | ||
41 | // Release is used to return a slot. Acquire must | |
42 | // be called as a pre-condition. | |
43 | func (s Semaphore) Release() { | |
44 | select { | |
45 | case <-s: | |
46 | default: | |
47 | panic("release without an acquire") | |
48 | } | |
49 | } | |
50 | ||
c680a8e1 RS |
51 | func resourceProvider(resourceType, explicitProvider string) string { |
52 | return config.ResourceProviderFullName(resourceType, explicitProvider) | |
bae9f6d2 JC |
53 | } |
54 | ||
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 { | |
59 | if s == needle { | |
60 | return true | |
61 | } | |
62 | } | |
63 | return false | |
64 | } | |
65 | ||
66 | // deduplicate a slice of strings | |
67 | func uniqueStrings(s []string) []string { | |
68 | if len(s) < 2 { | |
69 | return s | |
70 | } | |
71 | ||
72 | sort.Strings(s) | |
73 | result := make([]string, 1, len(s)) | |
74 | result[0] = s[0] | |
75 | for i := 1; i < len(s); i++ { | |
76 | if s[i] != result[len(result)-1] { | |
77 | result = append(result, s[i]) | |
78 | } | |
79 | } | |
80 | return result | |
81 | } |