Add thread safety
This commit is contained in:
parent
5a6d2abc23
commit
21577ddf74
@ -113,7 +113,7 @@ func (b *Birc) handleJoinPart(client *girc.Client, event girc.Event) {
|
|||||||
return
|
return
|
||||||
} else if b.GetBool("nosendjoinpart") {
|
} else if b.GetBool("nosendjoinpart") {
|
||||||
return
|
return
|
||||||
} else if b.isUserActive(event.Source.Name) || isKill(event.Last()) {
|
} else if isActive, _ := b.isUserActive(event.Source.Name); isActive || isKill(event.Last()) {
|
||||||
verbosequit := ""
|
verbosequit := ""
|
||||||
quitmsg := ""
|
quitmsg := ""
|
||||||
if len(event.Params) >= 1 {
|
if len(event.Params) >= 1 {
|
||||||
@ -129,7 +129,7 @@ func (b *Birc) handleJoinPart(client *girc.Client, event girc.Event) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if event.Source.Name != b.Nick {
|
if event.Source.Name != b.Nick {
|
||||||
if b.GetBool("nosendjoinpart") || !b.isUserActive(event.Source.Name) {
|
if isActive, _ := b.isUserActive(event.Source.Name); !isActive || b.GetBool("nosendjoinpart") {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
partmsg := ""
|
partmsg := ""
|
||||||
@ -171,7 +171,7 @@ func (b *Birc) handleNick(client *girc.Client, event girc.Event) {
|
|||||||
if len(event.Params) != 1 {
|
if len(event.Params) != 1 {
|
||||||
b.Log.Debugf("handleJoinPart: malformed nick change? %#v", event)
|
b.Log.Debugf("handleJoinPart: malformed nick change? %#v", event)
|
||||||
return
|
return
|
||||||
} else if b.isUserActive(event.Source.Name) {
|
} else if isActive, activeTime := b.isUserActive(event.Source.Name); isActive {
|
||||||
msg := config.Message{Username: "system",
|
msg := config.Message{Username: "system",
|
||||||
Text: event.Source.Name + " changed nick to " + event.Params[0],
|
Text: event.Source.Name + " changed nick to " + event.Params[0],
|
||||||
Channel: b.getPseudoChannel(),
|
Channel: b.getPseudoChannel(),
|
||||||
@ -181,7 +181,7 @@ func (b *Birc) handleNick(client *girc.Client, event girc.Event) {
|
|||||||
b.Remote <- msg
|
b.Remote <- msg
|
||||||
if b.ActivityTimeout != 0 {
|
if b.ActivityTimeout != 0 {
|
||||||
// This doesn't count as new activity, but it does preserve the value
|
// This doesn't count as new activity, but it does preserve the value
|
||||||
b.activeUsers[event.Params[0]] = b.activeUsers[event.Source.Name]
|
b.markUserActive(event.Params[0], activeTime)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -293,7 +293,7 @@ func (b *Birc) handlePrivMsg(client *girc.Client, event girc.Event) {
|
|||||||
b.Log.Debugf("<= Sending message from %s on %s to gateway", event.Params[0], b.Account)
|
b.Log.Debugf("<= Sending message from %s on %s to gateway", event.Params[0], b.Account)
|
||||||
if b.ActivityTimeout > 0 {
|
if b.ActivityTimeout > 0 {
|
||||||
b.Log.Debugf("<= Updating last-active time for user %s", event.Source.Name)
|
b.Log.Debugf("<= Updating last-active time for user %s", event.Source.Name)
|
||||||
b.activeUsers[event.Source.Name] = time.Now().Unix()
|
b.markUserActive(event.Source.Name, time.Now().Unix())
|
||||||
}
|
}
|
||||||
b.Remote <- rmsg
|
b.Remote <- rmsg
|
||||||
b.cleanActiveMap()
|
b.cleanActiveMap()
|
||||||
|
@ -10,6 +10,7 @@ import (
|
|||||||
"sort"
|
"sort"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/42wim/matterbridge/bridge"
|
"github.com/42wim/matterbridge/bridge"
|
||||||
@ -29,6 +30,7 @@ type Birc struct {
|
|||||||
names map[string][]string
|
names map[string][]string
|
||||||
activeUsers map[string]int64
|
activeUsers map[string]int64
|
||||||
activeUsersLastCleaned int64
|
activeUsersLastCleaned int64
|
||||||
|
activeUsersMutex sync.RWMutex
|
||||||
connected chan error
|
connected chan error
|
||||||
Local chan config.Message // local queue for flood control
|
Local chan config.Message // local queue for flood control
|
||||||
FirstConnection, authDone bool
|
FirstConnection, authDone bool
|
||||||
@ -432,20 +434,24 @@ func (b *Birc) getTLSConfig() (*tls.Config, error) {
|
|||||||
return tlsConfig, nil
|
return tlsConfig, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *Birc) isUserActive(nick string) bool {
|
func (b *Birc) isUserActive(nick string) (bool, int64) {
|
||||||
b.Log.Debugf("checking activity for %s", nick)
|
b.Log.Debugf("checking activity for %s", nick)
|
||||||
if b.ActivityTimeout == 0 {
|
if b.ActivityTimeout == 0 {
|
||||||
return true
|
return true, 0
|
||||||
} else if activeTime, ok := b.activeUsers[nick]; ok {
|
} else {
|
||||||
|
b.activeUsersMutex.RLock()
|
||||||
|
defer b.activeUsersMutex.RUnlock()
|
||||||
|
if activeTime, ok := b.activeUsers[nick]; ok {
|
||||||
now := time.Now().Unix()
|
now := time.Now().Unix()
|
||||||
b.Log.Debugf("last activity for %s was %d, currently %d", nick, activeTime, now)
|
b.Log.Debugf("last activity for %s was %d, currently %d", nick, activeTime, now)
|
||||||
if now < activeTime {
|
if now < activeTime {
|
||||||
b.Log.Errorf("User %s has active time in the future: %d", nick, activeTime)
|
b.Log.Errorf("User %s has active time in the future: %d", nick, activeTime)
|
||||||
return true // err on the side of caution
|
return true, now // err on the side of caution
|
||||||
}
|
}
|
||||||
return (now - activeTime) < b.ActivityTimeout
|
return (now - activeTime) < b.ActivityTimeout, activeTime
|
||||||
}
|
}
|
||||||
return false
|
}
|
||||||
|
return false, 0
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *Birc) getPseudoChannel() string {
|
func (b *Birc) getPseudoChannel() string {
|
||||||
@ -463,6 +469,8 @@ func (b *Birc) cleanActiveMap() {
|
|||||||
if b.ActivityTimeout == 0 || (b.activeUsersLastCleaned-now < b.ActivityTimeout) {
|
if b.ActivityTimeout == 0 || (b.activeUsersLastCleaned-now < b.ActivityTimeout) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
b.activeUsersMutex.Lock()
|
||||||
|
defer b.activeUsersMutex.Unlock()
|
||||||
for nick, activeTime := range b.activeUsers {
|
for nick, activeTime := range b.activeUsers {
|
||||||
if now-activeTime > b.ActivityTimeout {
|
if now-activeTime > b.ActivityTimeout {
|
||||||
b.Log.Debugf("last activity for %s was %d, currently %d. Deleting.", nick, activeTime, now)
|
b.Log.Debugf("last activity for %s was %d, currently %d. Deleting.", nick, activeTime, now)
|
||||||
@ -470,3 +478,9 @@ func (b *Birc) cleanActiveMap() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (b *Birc) markUserActive(nick string, activeTime int64) {
|
||||||
|
b.activeUsersMutex.Lock()
|
||||||
|
defer b.activeUsersMutex.Unlock()
|
||||||
|
b.activeUsers[nick] = activeTime
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user