]> git.immae.eu Git - github/fretlink/terraform-provider-statuscake.git/blob - vendor/github.com/hashicorp/terraform/helper/shadow/ordered_value.go
deps: use go modules for dep mgmt
[github/fretlink/terraform-provider-statuscake.git] / vendor / github.com / hashicorp / terraform / helper / shadow / ordered_value.go
1 package shadow
2
3 import (
4 "container/list"
5 "sync"
6 )
7
8 // OrderedValue is a struct that keeps track of a value in the order
9 // it is set. Each time Value() is called, it will return the most recent
10 // calls value then discard it.
11 //
12 // This is unlike Value that returns the same value once it is set.
13 type OrderedValue struct {
14 lock sync.Mutex
15 values *list.List
16 waiters *list.List
17 }
18
19 // Value returns the last value that was set, or blocks until one
20 // is received.
21 func (w *OrderedValue) Value() interface{} {
22 w.lock.Lock()
23
24 // If we have a pending value already, use it
25 if w.values != nil && w.values.Len() > 0 {
26 front := w.values.Front()
27 w.values.Remove(front)
28 w.lock.Unlock()
29 return front.Value
30 }
31
32 // No pending value, create a waiter
33 if w.waiters == nil {
34 w.waiters = list.New()
35 }
36
37 var val Value
38 w.waiters.PushBack(&val)
39 w.lock.Unlock()
40
41 // Return the value once we have it
42 return val.Value()
43 }
44
45 // SetValue sets the latest value.
46 func (w *OrderedValue) SetValue(v interface{}) {
47 w.lock.Lock()
48 defer w.lock.Unlock()
49
50 // If we have a waiter, notify it
51 if w.waiters != nil && w.waiters.Len() > 0 {
52 front := w.waiters.Front()
53 w.waiters.Remove(front)
54
55 val := front.Value.(*Value)
56 val.SetValue(v)
57 return
58 }
59
60 // Add it to the list of values
61 if w.values == nil {
62 w.values = list.New()
63 }
64
65 w.values.PushBack(v)
66 }