Introduce eventUpstreamDisconnected

This allows us to perform cleanup actions in the user goroutine. This
removes the need for pendingLISTsLock.
This commit is contained in:
Simon Ser 2020-03-28 00:51:58 +01:00
parent 0607b940e2
commit 1c3da31f2e
No known key found for this signature in database
GPG Key ID: 0FDE7BE0E88F5E48
3 changed files with 12 additions and 14 deletions

View File

@ -1080,9 +1080,6 @@ func (dc *downstreamConn) handleMessageRegistered(msg *irc.Message) error {
case "LIST": case "LIST":
// TODO: support ELIST when supported by all upstreams // TODO: support ELIST when supported by all upstreams
dc.user.pendingLISTsLock.Lock()
defer dc.user.pendingLISTsLock.Unlock()
pl := pendingLIST{ pl := pendingLIST{
downstreamID: dc.id, downstreamID: dc.id,
pendingCommands: make(map[int64]*irc.Message), pendingCommands: make(map[int64]*irc.Message),

View File

@ -63,7 +63,6 @@ type upstreamConn struct {
saslStarted bool saslStarted bool
// set of LIST commands in progress, per downstream // set of LIST commands in progress, per downstream
// access is synchronized with user.pendingLISTsLock
pendingLISTDownstreamSet map[uint64]struct{} pendingLISTDownstreamSet map[uint64]struct{}
logs map[string]entityLog logs map[string]entityLog
@ -151,10 +150,6 @@ func (uc *upstreamConn) Close() error {
return fmt.Errorf("upstream connection already closed") return fmt.Errorf("upstream connection already closed")
} }
close(uc.closed) close(uc.closed)
for _, log := range uc.logs {
log.file.Close()
}
uc.endPendingLists(true)
return nil return nil
} }
@ -192,8 +187,6 @@ func (uc *upstreamConn) isChannel(entity string) bool {
} }
func (uc *upstreamConn) getPendingList() *pendingLIST { func (uc *upstreamConn) getPendingList() *pendingLIST {
uc.user.pendingLISTsLock.Lock()
defer uc.user.pendingLISTsLock.Unlock()
for _, pl := range uc.user.pendingLISTs { for _, pl := range uc.user.pendingLISTs {
if _, ok := pl.pendingCommands[uc.network.ID]; !ok { if _, ok := pl.pendingCommands[uc.network.ID]; !ok {
continue continue
@ -205,8 +198,6 @@ func (uc *upstreamConn) getPendingList() *pendingLIST {
func (uc *upstreamConn) endPendingLists(all bool) (found bool) { func (uc *upstreamConn) endPendingLists(all bool) (found bool) {
found = false found = false
uc.user.pendingLISTsLock.Lock()
defer uc.user.pendingLISTsLock.Unlock()
for i := 0; i < len(uc.user.pendingLISTs); i++ { for i := 0; i < len(uc.user.pendingLISTs); i++ {
pl := uc.user.pendingLISTs[i] pl := uc.user.pendingLISTs[i]
if _, ok := pl.pendingCommands[uc.network.ID]; !ok { if _, ok := pl.pendingCommands[uc.network.ID]; !ok {

14
user.go
View File

@ -14,6 +14,10 @@ type eventUpstreamMessage struct {
uc *upstreamConn uc *upstreamConn
} }
type eventUpstreamDisconnected struct {
uc *upstreamConn
}
type eventDownstreamMessage struct { type eventDownstreamMessage struct {
msg *irc.Message msg *irc.Message
dc *downstreamConn dc *downstreamConn
@ -75,6 +79,7 @@ func (net *network) run() {
uc.logger.Printf("failed to handle messages: %v", err) uc.logger.Printf("failed to handle messages: %v", err)
} }
uc.Close() uc.Close()
net.user.events <- eventUpstreamDisconnected{uc}
net.lock.Lock() net.lock.Lock()
net.conn = nil net.conn = nil
@ -98,8 +103,7 @@ type user struct {
downstreamConns []*downstreamConn downstreamConns []*downstreamConn
// LIST commands in progress // LIST commands in progress
pendingLISTsLock sync.Mutex pendingLISTs []pendingLIST
pendingLISTs []pendingLIST
} }
type pendingLIST struct { type pendingLIST struct {
@ -163,6 +167,12 @@ func (u *user) run() {
for e := range u.events { for e := range u.events {
switch e := e.(type) { switch e := e.(type) {
case eventUpstreamDisconnected:
uc := e.uc
for _, log := range uc.logs {
log.file.Close()
}
uc.endPendingLists(true)
case eventUpstreamMessage: case eventUpstreamMessage:
msg, uc := e.msg, e.uc msg, uc := e.msg, e.uc
if uc.isClosed() { if uc.isClosed() {