summaryrefslogtreecommitdiff
path: root/vendor/github.com/jtolds/gls/context.go
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/github.com/jtolds/gls/context.go')
-rw-r--r--vendor/github.com/jtolds/gls/context.go153
1 files changed, 0 insertions, 153 deletions
diff --git a/vendor/github.com/jtolds/gls/context.go b/vendor/github.com/jtolds/gls/context.go
deleted file mode 100644
index 618a171..0000000
--- a/vendor/github.com/jtolds/gls/context.go
+++ /dev/null
@@ -1,153 +0,0 @@
-// Package gls implements goroutine-local storage.
-package gls
-
-import (
- "sync"
-)
-
-var (
- mgrRegistry = make(map[*ContextManager]bool)
- mgrRegistryMtx sync.RWMutex
-)
-
-// Values is simply a map of key types to value types. Used by SetValues to
-// set multiple values at once.
-type Values map[interface{}]interface{}
-
-// ContextManager is the main entrypoint for interacting with
-// Goroutine-local-storage. You can have multiple independent ContextManagers
-// at any given time. ContextManagers are usually declared globally for a given
-// class of context variables. You should use NewContextManager for
-// construction.
-type ContextManager struct {
- mtx sync.Mutex
- values map[uint]Values
-}
-
-// NewContextManager returns a brand new ContextManager. It also registers the
-// new ContextManager in the ContextManager registry which is used by the Go
-// method. ContextManagers are typically defined globally at package scope.
-func NewContextManager() *ContextManager {
- mgr := &ContextManager{values: make(map[uint]Values)}
- mgrRegistryMtx.Lock()
- defer mgrRegistryMtx.Unlock()
- mgrRegistry[mgr] = true
- return mgr
-}
-
-// Unregister removes a ContextManager from the global registry, used by the
-// Go method. Only intended for use when you're completely done with a
-// ContextManager. Use of Unregister at all is rare.
-func (m *ContextManager) Unregister() {
- mgrRegistryMtx.Lock()
- defer mgrRegistryMtx.Unlock()
- delete(mgrRegistry, m)
-}
-
-// SetValues takes a collection of values and a function to call for those
-// values to be set in. Anything further down the stack will have the set
-// values available through GetValue. SetValues will add new values or replace
-// existing values of the same key and will not mutate or change values for
-// previous stack frames.
-// SetValues is slow (makes a copy of all current and new values for the new
-// gls-context) in order to reduce the amount of lookups GetValue requires.
-func (m *ContextManager) SetValues(new_values Values, context_call func()) {
- if len(new_values) == 0 {
- context_call()
- return
- }
-
- mutated_keys := make([]interface{}, 0, len(new_values))
- mutated_vals := make(Values, len(new_values))
-
- EnsureGoroutineId(func(gid uint) {
- m.mtx.Lock()
- state, found := m.values[gid]
- if !found {
- state = make(Values, len(new_values))
- m.values[gid] = state
- }
- m.mtx.Unlock()
-
- for key, new_val := range new_values {
- mutated_keys = append(mutated_keys, key)
- if old_val, ok := state[key]; ok {
- mutated_vals[key] = old_val
- }
- state[key] = new_val
- }
-
- defer func() {
- if !found {
- m.mtx.Lock()
- delete(m.values, gid)
- m.mtx.Unlock()
- return
- }
-
- for _, key := range mutated_keys {
- if val, ok := mutated_vals[key]; ok {
- state[key] = val
- } else {
- delete(state, key)
- }
- }
- }()
-
- context_call()
- })
-}
-
-// GetValue will return a previously set value, provided that the value was set
-// by SetValues somewhere higher up the stack. If the value is not found, ok
-// will be false.
-func (m *ContextManager) GetValue(key interface{}) (
- value interface{}, ok bool) {
- gid, ok := GetGoroutineId()
- if !ok {
- return nil, false
- }
-
- m.mtx.Lock()
- state, found := m.values[gid]
- m.mtx.Unlock()
-
- if !found {
- return nil, false
- }
- value, ok = state[key]
- return value, ok
-}
-
-func (m *ContextManager) getValues() Values {
- gid, ok := GetGoroutineId()
- if !ok {
- return nil
- }
- m.mtx.Lock()
- state, _ := m.values[gid]
- m.mtx.Unlock()
- return state
-}
-
-// Go preserves ContextManager values and Goroutine-local-storage across new
-// goroutine invocations. The Go method makes a copy of all existing values on
-// all registered context managers and makes sure they are still set after
-// kicking off the provided function in a new goroutine. If you don't use this
-// Go method instead of the standard 'go' keyword, you will lose values in
-// ContextManagers, as goroutines have brand new stacks.
-func Go(cb func()) {
- mgrRegistryMtx.RLock()
- defer mgrRegistryMtx.RUnlock()
-
- for mgr := range mgrRegistry {
- values := mgr.getValues()
- if len(values) > 0 {
- cb = func(mgr *ContextManager, cb func()) func() {
- return func() { mgr.SetValues(values, cb) }
- }(mgr, cb)
- }
- }
-
- go cb()
-}