summaryrefslogtreecommitdiff
path: root/vendor/github.com/hashicorp/terraform/helper/shadow/ordered_value.go
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/github.com/hashicorp/terraform/helper/shadow/ordered_value.go')
-rw-r--r--vendor/github.com/hashicorp/terraform/helper/shadow/ordered_value.go66
1 files changed, 66 insertions, 0 deletions
diff --git a/vendor/github.com/hashicorp/terraform/helper/shadow/ordered_value.go b/vendor/github.com/hashicorp/terraform/helper/shadow/ordered_value.go
new file mode 100644
index 00000000..0a43d4d4
--- /dev/null
+++ b/vendor/github.com/hashicorp/terraform/helper/shadow/ordered_value.go
@@ -0,0 +1,66 @@
+package shadow
+
+import (
+ "container/list"
+ "sync"
+)
+
+// OrderedValue is a struct that keeps track of a value in the order
+// it is set. Each time Value() is called, it will return the most recent
+// calls value then discard it.
+//
+// This is unlike Value that returns the same value once it is set.
+type OrderedValue struct {
+ lock sync.Mutex
+ values *list.List
+ waiters *list.List
+}
+
+// Value returns the last value that was set, or blocks until one
+// is received.
+func (w *OrderedValue) Value() interface{} {
+ w.lock.Lock()
+
+ // If we have a pending value already, use it
+ if w.values != nil && w.values.Len() > 0 {
+ front := w.values.Front()
+ w.values.Remove(front)
+ w.lock.Unlock()
+ return front.Value
+ }
+
+ // No pending value, create a waiter
+ if w.waiters == nil {
+ w.waiters = list.New()
+ }
+
+ var val Value
+ w.waiters.PushBack(&val)
+ w.lock.Unlock()
+
+ // Return the value once we have it
+ return val.Value()
+}
+
+// SetValue sets the latest value.
+func (w *OrderedValue) SetValue(v interface{}) {
+ w.lock.Lock()
+ defer w.lock.Unlock()
+
+ // If we have a waiter, notify it
+ if w.waiters != nil && w.waiters.Len() > 0 {
+ front := w.waiters.Front()
+ w.waiters.Remove(front)
+
+ val := front.Value.(*Value)
+ val.SetValue(v)
+ return
+ }
+
+ // Add it to the list of values
+ if w.values == nil {
+ w.values = list.New()
+ }
+
+ w.values.PushBack(v)
+}