github.com/whamcloud/lemur@v0.0.0-20190827193804-4655df8a52af/cmd/lhsmd/agent/endpoints.go (about) 1 // Copyright (c) 2018 DDN. All rights reserved. 2 // Use of this source code is governed by a MIT-style 3 // license that can be found in the LICENSE file. 4 5 package agent 6 7 import ( 8 "errors" 9 "sync" 10 "sync/atomic" 11 ) 12 13 type ( 14 // Handle is an endpoint handle (unique id) 15 Handle uint64 16 17 // Endpoints represents a collection of Endpoints and their handles 18 Endpoints struct { 19 sync.Mutex 20 nextHandle int64 21 endpoints map[uint32]Endpoint 22 handles map[Handle]uint32 23 } 24 25 // Endpoint defines an interface for HSM backends 26 Endpoint interface { 27 Send(*Action) 28 } 29 ) 30 31 // NewEndpoints returns a new *Endpoints instance 32 func NewEndpoints() *Endpoints { 33 return &Endpoints{ 34 endpoints: make(map[uint32]Endpoint), 35 handles: make(map[Handle]uint32), 36 } 37 } 38 39 // Get returns an Endpoint or nil, given a lookup id 40 func (all *Endpoints) Get(a uint32) (Endpoint, bool) { 41 all.Lock() 42 defer all.Unlock() 43 return all.get(a) 44 } 45 46 // GetWithHandle returns an Endpoint or nil, given a Handle 47 func (all *Endpoints) GetWithHandle(h *Handle) (Endpoint, bool) { 48 all.Lock() 49 defer all.Unlock() 50 return all.getWithHandle(h) 51 } 52 53 func (all *Endpoints) get(a uint32) (Endpoint, bool) { 54 // all must already be locked. 55 e, ok := all.endpoints[a] 56 if !ok { 57 return nil, ok 58 } 59 return e, true 60 } 61 62 func (all *Endpoints) getWithHandle(h *Handle) (Endpoint, bool) { 63 // all must already be locked. 64 a, ok := all.handles[*h] 65 if !ok { 66 return nil, ok 67 } 68 69 return all.get(a) 70 } 71 72 func (all *Endpoints) newHandle() *Handle { 73 h := Handle(atomic.AddInt64(&all.nextHandle, 1)) 74 return &h 75 } 76 77 // Add registers a new Endpoint 78 func (all *Endpoints) Add(a uint32, e Endpoint) (*Handle, error) { 79 h := all.newHandle() 80 all.Lock() 81 defer all.Unlock() 82 83 if _, ok := all.get(a); ok { 84 return nil, errors.New("Endpoint already exists") 85 } 86 87 all.endpoints[a] = e 88 all.handles[*h] = a 89 return h, nil 90 } 91 92 // NewHandle returns a new *Handle 93 func (all *Endpoints) NewHandle(a uint32) (*Handle, error) { 94 all.Lock() 95 defer all.Unlock() 96 97 if _, ok := all.get(a); !ok { 98 return nil, errors.New("Endpoint does not exist") 99 } 100 101 h := all.newHandle() 102 all.handles[*h] = a 103 return h, nil 104 105 } 106 107 // RemoveHandle removes the given handle from the collection of handles 108 func (all *Endpoints) RemoveHandle(h *Handle) { 109 all.Lock() 110 defer all.Unlock() 111 112 delete(all.handles, *h) 113 } 114 115 // Remove removes the given handle and its associated Endpoint 116 func (all *Endpoints) Remove(h *Handle) Endpoint { 117 all.Lock() 118 defer all.Unlock() 119 a, ok := all.handles[*h] 120 if !ok { 121 return nil 122 } 123 124 if e, ok := all.get(a); ok { 125 delete(all.handles, *h) 126 delete(all.endpoints, a) 127 return e 128 } 129 130 return nil 131 }