diff options
author | Carl Baldwin <carl@ecbaldwin.net> | 2019-10-11 13:11:44 -0600 |
---|---|---|
committer | FUJITA Tomonori <fujita.tomonori@gmail.com> | 2019-10-15 20:21:18 +0900 |
commit | 65929fe5245f715322286f683cbcf3d15699e8b4 (patch) | |
tree | ecc0962196b84e1d43f15a5b8b1c65a70b710c85 | |
parent | ea87564b5b5d332ab48b6619c4a365559111e2c9 (diff) |
Keep Lock and defer Unlock together
The best way to ensure that a lock will always get unlocked is to
defer the unlock immediately after locking. Otherwise, adding a return
statement in the middle somewhere *could* result in forgetting to
release the lock. One of these two cases has that.
This technique uses an anonymous function/closure within the larger
method to confine the scope of the lock and ensure that it will be
unlocked in every case.
-rw-r--r-- | internal/pkg/table/policy.go | 43 |
1 files changed, 26 insertions, 17 deletions
diff --git a/internal/pkg/table/policy.go b/internal/pkg/table/policy.go index 95460fca..3ced3b96 100644 --- a/internal/pkg/table/policy.go +++ b/internal/pkg/table/policy.go @@ -3440,18 +3440,24 @@ func (r *RoutingPolicy) reload(c config.RoutingPolicy) error { } func (r *RoutingPolicy) GetDefinedSet(typ DefinedType, name string) (*config.DefinedSets, error) { - r.mu.RLock() + dl, err := func() (DefinedSetList, error) { + r.mu.RLock() + defer r.mu.RUnlock() - set, ok := r.definedSetMap[typ] - if !ok { - return nil, fmt.Errorf("invalid defined-set type: %d", typ) - } + set, ok := r.definedSetMap[typ] + if !ok { + return nil, fmt.Errorf("invalid defined-set type: %d", typ) + } - var dl DefinedSetList - for _, s := range set { - dl = append(dl, s) + var dl DefinedSetList + for _, s := range set { + dl = append(dl, s) + } + return dl, nil + }() + if err != nil { + return nil, err } - r.mu.RUnlock() sort.Sort(dl) @@ -3586,16 +3592,19 @@ func (r *RoutingPolicy) DeleteStatement(st *Statement, all bool) (err error) { } func (r *RoutingPolicy) GetPolicy(name string) []*config.PolicyDefinition { - r.mu.RLock() + ps := func() Policies { + r.mu.RLock() + defer r.mu.RUnlock() - var ps Policies - for _, p := range r.policyMap { - if name != "" && name != p.Name { - continue + var ps Policies + for _, p := range r.policyMap { + if name != "" && name != p.Name { + continue + } + ps = append(ps, p) } - ps = append(ps, p) - } - r.mu.RUnlock() + return ps + }() sort.Sort(ps) |