Introduce eventUpstreamDisconnected
This allows us to perform cleanup actions in the user goroutine. This removes the need for pendingLISTsLock.
This commit is contained in:
parent
0607b940e2
commit
1c3da31f2e
@ -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),
|
||||||
|
@ -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
14
user.go
@ -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() {
|
||||||
|
Loading…
Reference in New Issue
Block a user