singchia / geminio

A hyper application layer networking framework with messaging, rpc, bidirectional-rpc, multiplexer and client-server consistency.
Apache License 2.0
85 stars 26 forks source link

bug: panic in dialogue close which may be called after fini #90

Closed singchia closed 7 months ago

singchia commented 7 months ago

stack:

goroutine 110119 [running]:
github.com/jumboframes/armorigo/synchub.(*SyncHub).Add(0x0, {0x56b2a0?, 0xc0461ea6f8}, {0xc009179ee8, 0x1, 0xc0052bc630?})
    /Users/zhaizenghui/GOPATH/pkg/mod/github.com/jumboframes/armorigo@v0.4.0-rc.1/synchub/synchub.go:190 +0x179
github.com/jumboframes/armorigo/synchub.(*SyncHub).New(...)
    /Users/zhaizenghui/GOPATH/pkg/mod/github.com/jumboframes/armorigo@v0.4.0-rc.1/synchub/synchub.go:175
github.com/singchia/geminio/multiplexer.(*dialogue).CloseWait.func1()
    /Users/zhaizenghui/GOPATH/pkg/mod/github.com/singchia/geminio@v1.1.5-rc.2/multiplexer/dialogue.go:645 +0xc5
github.com/singchia/geminio/pkg/sync.(*Once).doSlow(0x5092c0?, 0xc009120a10?)
    /Users/zhaizenghui/GOPATH/pkg/mod/github.com/singchia/geminio@v1.1.5-rc.2/pkg/sync/once.go:78 +0xbf
github.com/singchia/geminio/pkg/sync.(*Once).Do(...)
    /Users/zhaizenghui/GOPATH/pkg/mod/github.com/singchia/geminio@v1.1.5-rc.2/pkg/sync/once.go:66
github.com/singchia/geminio/multiplexer.(*dialogue).CloseWait(0xc0091319e0?)
    /Users/zhaizenghui/GOPATH/pkg/mod/github.com/singchia/geminio@v1.1.5-rc.2/multiplexer/dialogue.go:643 +0x3f
github.com/singchia/geminio/multiplexer.(*dialogueMgr).Close.func1(0xc009120a10?)
    /Users/zhaizenghui/GOPATH/pkg/mod/github.com/singchia/geminio@v1.1.5-rc.2/multiplexer/dialogue_mgr.go:433 +0x49
created by github.com/singchia/geminio/multiplexer.(*dialogueMgr).Close in goroutine 110118
    /Users/zhaizenghui/GOPATH/pkg/mod/github.com/singchia/geminio@v1.1.5-rc.2/multiplexer/dialogue_mgr.go:431 +0x1bb

source:

func (dg *dialogue) CloseWait() {
    // send close packet and wait for the end
    dg.closeOnce.Do(func() {
        pkt := dg.pf.NewDismissPacket(dg.dialogueID)
        dg.closewait = dg.shub.New(pkt.PacketID, synchub.WithTimeout(30*time.Second)) => BUG here
        dg.mtx.RLock()
        if !dg.dialogueOK {
            dg.mtx.RUnlock()
            return
        }

        dg.log.Debugf("dialogue is closing, clientID: %d, dialogueID: %d",
            dg.cn.ClientID(), dg.dialogueID)

        dg.writeInCh <- pkt
        dg.mtx.RUnlock()
        // the sync shouldn't be locked
        event := <-dg.closewait.C()
        if event.Error != nil {
            dg.log.Debugf("dialogue close wait err: %s, clientID: %d, peerDialogueID: %d, dialogueID: %d",
                event.Error, dg.cn.ClientID(), dg.peerNegotiatingID, dg.dialogueID)
            if event.Error == synchub.ErrSyncTimeout {
                // timeout and exit the dialogue
                dg.closeIO()
            }
            return
        }
        dg.log.Debugf("dialogue closed, clientID: %d, dialogueID: %d",
            dg.cn.ClientID(), dg.dialogueID)
        return
    })
}
singchia commented 7 months ago

91 fixed