From bae9f6d2fd5eb5bc80929bd393932b23f14d7c93 Mon Sep 17 00:00:00 2001 From: Jake Champlin Date: Tue, 6 Jun 2017 12:40:07 -0400 Subject: Initial transfer of provider code --- .../hashicorp/terraform/helper/shadow/value.go | 79 ++++++++++++++++++++++ 1 file changed, 79 insertions(+) create mode 100644 vendor/github.com/hashicorp/terraform/helper/shadow/value.go (limited to 'vendor/github.com/hashicorp/terraform/helper/shadow/value.go') diff --git a/vendor/github.com/hashicorp/terraform/helper/shadow/value.go b/vendor/github.com/hashicorp/terraform/helper/shadow/value.go new file mode 100644 index 0000000..2413335 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform/helper/shadow/value.go @@ -0,0 +1,79 @@ +package shadow + +import ( + "errors" + "sync" +) + +// ErrClosed is returned by any closed values. +// +// A "closed value" is when the shadow has been notified that the real +// side is complete and any blocking values will _never_ be satisfied +// in the future. In this case, this error is returned. If a value is already +// available, that is still returned. +var ErrClosed = errors.New("shadow closed") + +// Value is a struct that coordinates a value between two +// parallel routines. It is similar to atomic.Value except that when +// Value is called if it isn't set it will wait for it. +// +// The Value can be closed with Close, which will cause any future +// blocking operations to return immediately with ErrClosed. +type Value struct { + lock sync.Mutex + cond *sync.Cond + value interface{} + valueSet bool +} + +// Close closes the value. This can never fail. For a definition of +// "close" see the struct docs. +func (w *Value) Close() error { + w.lock.Lock() + set := w.valueSet + w.lock.Unlock() + + // If we haven't set the value, set it + if !set { + w.SetValue(ErrClosed) + } + + // Done + return nil +} + +// Value returns the value that was set. +func (w *Value) Value() interface{} { + w.lock.Lock() + defer w.lock.Unlock() + + // If we already have a value just return + for !w.valueSet { + // No value, setup the condition variable if we have to + if w.cond == nil { + w.cond = sync.NewCond(&w.lock) + } + + // Wait on it + w.cond.Wait() + } + + // Return the value + return w.value +} + +// SetValue sets the value. +func (w *Value) SetValue(v interface{}) { + w.lock.Lock() + defer w.lock.Unlock() + + // Set the value + w.valueSet = true + w.value = v + + // If we have a condition, clear it + if w.cond != nil { + w.cond.Broadcast() + w.cond = nil + } +} -- cgit v1.2.3