From 32f2b078c36ea144f5d78021517dbeb0b3e8c32d Mon Sep 17 00:00:00 2001 From: "kayos@tcp.direct" Date: Mon, 11 Jul 2022 22:36:36 -0700 Subject: [PATCH] Switch UserPerms to cmap and fix panic --- go.mod | 2 ++ go.sum | 2 ++ modes.go | 30 +++++++++++------------------- state.go | 2 +- 4 files changed, 16 insertions(+), 20 deletions(-) diff --git a/go.mod b/go.mod index 3c0f09d..fd5d0ac 100644 --- a/go.mod +++ b/go.mod @@ -6,3 +6,5 @@ require ( github.com/araddon/dateparse v0.0.0-20210429162001-6b43995a97de github.com/orcaman/concurrent-map v1.0.0 ) + +require github.com/dvyukov/go-fuzz v0.0.0-20220220162807-a217d9bdbece // indirect diff --git a/go.sum b/go.sum index 74c5631..4fe84c0 100644 --- a/go.sum +++ b/go.sum @@ -2,6 +2,8 @@ github.com/araddon/dateparse v0.0.0-20210429162001-6b43995a97de h1:FxWPpzIjnTlhP github.com/araddon/dateparse v0.0.0-20210429162001-6b43995a97de/go.mod h1:DCaWoUhZrYW9p1lxo/cm8EmUOOzAPSEZNGF2DK1dJgw= github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/dvyukov/go-fuzz v0.0.0-20220220162807-a217d9bdbece h1:6BGhEtGBmkgr8TKLjMBBMpvM/fK0GHj4prrkK1tYPcA= +github.com/dvyukov/go-fuzz v0.0.0-20220220162807-a217d9bdbece/go.mod h1:11Gm+ccJnvAhCNLlf5+cS9KjtbaD5I5zaZpFMsTHWTw= github.com/mattn/go-runewidth v0.0.10/go.mod h1:RAqKPSqVFrSLVXbA8x7dzmKdmGzieGRCM46jaSJTDAk= github.com/orcaman/concurrent-map v1.0.0 h1:I/2A2XPCb4IuQWcQhBhSwGfiuybl/J0ev9HDbW65HOY= github.com/orcaman/concurrent-map v1.0.0/go.mod h1:Lu3tH6HLW3feq74c2GC+jIMS/K2CFcDWnWD9XkenwhI= diff --git a/modes.go b/modes.go index 255e1c5..77f2370 100644 --- a/modes.go +++ b/modes.go @@ -7,7 +7,8 @@ package girc import ( "encoding/json" "strings" - "sync" + + cmap "github.com/orcaman/concurrent-map" ) // CMode represents a single step of a given mode change. @@ -395,50 +396,41 @@ func (s *state) userPrefixes() string { // UserPerms contains all of the permissions for each channel the user is // in. type UserPerms struct { - mu sync.RWMutex - channels map[string]Perms + channels cmap.ConcurrentMap } // Copy returns a deep copy of the channel permissions. func (p *UserPerms) Copy() (perms *UserPerms) { np := &UserPerms{ - channels: make(map[string]Perms), + channels: cmap.New(), } - for key := range p.channels { - np.channels[key] = p.channels[key] + for tuple := range p.channels.IterBuffered() { + np.channels.Set(tuple.Key, tuple.Val) } return np } // MarshalJSON implements json.Marshaler. func (p *UserPerms) MarshalJSON() ([]byte, error) { - p.mu.Lock() out, err := json.Marshal(&p.channels) - p.mu.Unlock() - return out, err } // Lookup looks up the users permissions for a given channel. ok is false // if the user is not in the given channel. func (p *UserPerms) Lookup(channel string) (perms Perms, ok bool) { - p.mu.RLock() - defer p.mu.RUnlock() - perms, ok = p.channels[ToRFC1459(channel)] - + var permsi interface{} + permsi, ok = p.channels.Get(ToRFC1459(channel)) + perms = permsi.(Perms) return perms, ok } func (p *UserPerms) set(channel string, perms Perms) { - p.mu.Lock() - p.channels[ToRFC1459(channel)] = perms - p.mu.Unlock() + p.channels.Set(ToRFC1459(channel), perms) } func (p *UserPerms) remove(channel string) { - p.mu.Lock() - delete(p.channels, ToRFC1459(channel)) - p.mu.Unlock() + p.channels.Remove(ToRFC1459(channel)) } // Perms contains all channel-based user permissions. The minimum op, and diff --git a/state.go b/state.go index 1ee8289..7aa03b0 100644 --- a/state.go +++ b/state.go @@ -459,7 +459,7 @@ func (s *state) createUser(src *Source) (u *User, ok bool) { FirstSeen: time.Now(), LastActive: time.Now(), Network: s.client.NetworkName(), - Perms: &UserPerms{channels: make(map[string]Perms)}, + Perms: &UserPerms{channels: cmap.New()}, } s.users.Set(src.ID(), u)