Skip to content

Commit

Permalink
fix data races with mutexes
Browse files Browse the repository at this point in the history
  • Loading branch information
dmitris committed Apr 29, 2020
1 parent e423aaa commit 52a5fe2
Show file tree
Hide file tree
Showing 4 changed files with 32 additions and 4 deletions.
7 changes: 5 additions & 2 deletions global.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,17 +13,20 @@ var (
memoryStore *GryffinStore
logWriter io.Writer
memoryStoreMu sync.Mutex
logWriterMu sync.Mutex
)

// SetMemoryStore sets the package internal global variable
// for the memory store.
func SetMemoryStore(m *GryffinStore) {
m.Lock()
memoryStoreMu.Lock()
memoryStore = m
m.Unlock()
memoryStoreMu.Unlock()
}

// SetLogWriter sets the log writer.
func SetLogWriter(w io.Writer) {
logWriterMu.Lock()
logWriter = w
logWriterMu.Unlock()
}
2 changes: 2 additions & 0 deletions gryffin.go
Original file line number Diff line number Diff line change
Expand Up @@ -418,6 +418,8 @@ func (s *Scan) Log(v interface{}) {
if logWriter == nil {
return
}
logWriterMu.Lock()
encoder := json.NewEncoder(logWriter)
encoder.Encode(v)
logWriterMu.Unlock()
}
10 changes: 9 additions & 1 deletion html-distance/bktree.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,16 @@
package distance

import (
"sync"

"github.com/mfonda/simhash"
)

// Oracle answers the query if a fingerprint has been seen.
type Oracle struct {
fingerprint uint64 // node value.
nodes [65]*Oracle // leaf nodes
mu sync.Mutex
}

// NewOracle return an oracle that could tell if the fingerprint has been seen or not.
Expand All @@ -45,6 +48,8 @@ func (n *Oracle) See(f uint64) *Oracle {
}

// the target node is already set,
n.mu.Lock()
defer n.mu.Unlock()
if c := n.nodes[d]; c != nil {
return c.See(f)
}
Expand All @@ -65,7 +70,10 @@ func (n *Oracle) Seen(f uint64, r uint8) bool {
if k > 64 {
break
}
if c := n.nodes[k]; c != nil {
n.mu.Lock()
c := n.nodes[k]
n.mu.Unlock()
if c != nil {
if c.Seen(f, r) {
return true
}
Expand Down
17 changes: 16 additions & 1 deletion session.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (
"encoding/json"
"fmt"
"strconv"
"sync"
"time"

distance "github.com/yahoo/gryffin/html-distance"
Expand All @@ -18,12 +19,13 @@ type GryffinStore struct {
Oracles map[string]*distance.Oracle
Hashes map[string]bool
Hits map[string]int
Mu sync.RWMutex
// store data.Store - currently unused, TODO: use or remove
snd chan []byte
rcv chan []byte
}

// PublishMessage
// PublishMessage is the data in the messages handled by Gryffin.
type PublishMessage struct {
F string // function, i.e. See or Seen
T string // type (kind), i.e. oracle or hash
Expand Down Expand Up @@ -103,12 +105,17 @@ func (s *GryffinStore) Seen(prefix string, kind string, v uint64, r uint8) bool

switch kind {
case "oracle":
s.Mu.RLock()
if oracle, ok := s.Oracles[prefix]; ok {
s.Mu.RUnlock()
return oracle.Seen(v, r)
}
s.Mu.RUnlock()
case "hash":
k := prefix + "/" + strconv.FormatUint(v, 10)
s.Mu.RLock()
_, ok := s.Hashes[k]
s.Mu.RUnlock()
return ok
}
return false
Expand All @@ -117,10 +124,14 @@ func (s *GryffinStore) Seen(prefix string, kind string, v uint64, r uint8) bool
func (s *GryffinStore) oracleSee(prefix string, f uint64, localOnly bool) {
k := prefix
// Local update
s.Mu.RLock()
oracle, ok := s.Oracles[k]
s.Mu.RUnlock()
if !ok {
s.Mu.Lock()
s.Oracles[k] = distance.NewOracle()
oracle = s.Oracles[k]
s.Mu.Unlock()
}
oracle.See(f)

Expand All @@ -136,7 +147,9 @@ func (s *GryffinStore) oracleSee(prefix string, f uint64, localOnly bool) {

func (s *GryffinStore) hashesSee(prefix string, h uint64, localOnly bool) {
k := prefix + "/" + strconv.FormatUint(h, 10)
s.Mu.Lock()
s.Hashes[k] = true
s.Mu.Unlock()
// Remote update
if !localOnly && s.snd != nil {
go func() {
Expand All @@ -150,6 +163,8 @@ func (s *GryffinStore) Hit(prefix string) bool {
// prefix is domain.
ts := time.Now().Truncate(5 * time.Second).Unix()
k := prefix + "/" + strconv.FormatInt(ts, 10)
s.Mu.Lock()
defer s.Mu.Unlock()
if v, ok := s.Hits[k]; ok {
if v >= 5 {
return false
Expand Down

0 comments on commit 52a5fe2

Please sign in to comment.