github.com/xsb/terraform@v0.6.13-0.20160314145438-fe415c2f09d7/helper/mutexkv/mutexkv.go (about) 1 package mutexkv 2 3 import ( 4 "log" 5 "sync" 6 ) 7 8 // MutexKV is a simple key/value store for arbitrary mutexes. It can be used to 9 // serialize changes across arbitrary collaborators that share knowledge of the 10 // keys they must serialize on. 11 // 12 // The initial use case is to let aws_security_group_rule resources serialize 13 // their access to individual security groups based on SG ID. 14 type MutexKV struct { 15 lock sync.Mutex 16 store map[string]*sync.Mutex 17 } 18 19 // Locks the mutex for the given key. Caller is responsible for calling Unlock 20 // for the same key 21 func (m *MutexKV) Lock(key string) { 22 log.Printf("[DEBUG] Locking %q", key) 23 m.get(key).Lock() 24 log.Printf("[DEBUG] Locked %q", key) 25 } 26 27 // Unlock the mutex for the given key. Caller must have called Lock for the same key first 28 func (m *MutexKV) Unlock(key string) { 29 log.Printf("[DEBUG] Unlocking %q", key) 30 m.get(key).Unlock() 31 log.Printf("[DEBUG] Unlocked %q", key) 32 } 33 34 // Returns a mutex for the given key, no guarantee of its lock status 35 func (m *MutexKV) get(key string) *sync.Mutex { 36 m.lock.Lock() 37 defer m.lock.Unlock() 38 mutex, ok := m.store[key] 39 if !ok { 40 mutex = &sync.Mutex{} 41 m.store[key] = mutex 42 } 43 return mutex 44 } 45 46 // Returns a properly initalized MutexKV 47 func NewMutexKV() *MutexKV { 48 return &MutexKV{ 49 store: make(map[string]*sync.Mutex), 50 } 51 }