Skip to content

Commit

Permalink
让Codec可选择性的实现SendChan的清理工作
Browse files Browse the repository at this point in the history
  • Loading branch information
bg5sbk committed Oct 19, 2016
1 parent 43c974a commit 61bb850
Show file tree
Hide file tree
Showing 2 changed files with 35 additions and 11 deletions.
4 changes: 4 additions & 0 deletions api.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,10 @@ type Codec interface {
Close() error
}

type ClearSendChan interface {
ClearSendChan(<-chan interface{})
}

func Serve(network, address string, protocol Protocol, sendChanSize int) (*Server, error) {
listener, err := net.Listen(network, address)
if err != nil {
Expand Down
42 changes: 31 additions & 11 deletions session.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,11 @@ var SessionBlockedError = errors.New("Session Blocked")
var globalSessionId uint64

type Session struct {
id uint64
codec Codec
manager *Manager
sendChan chan interface{}
id uint64
codec Codec
manager *Manager
sendChan chan interface{}
sendMutex sync.RWMutex

closeFlag int32
closeChan chan int
Expand Down Expand Up @@ -54,8 +55,18 @@ func (session *Session) IsClosed() bool {

func (session *Session) Close() error {
if atomic.CompareAndSwapInt32(&session.closeFlag, 0, 1) {
err := session.codec.Close()
close(session.closeChan)

if session.sendChan != nil {
session.sendMutex.Lock()
close(session.sendChan)
if clear, ok := session.codec.(ClearSendChan); ok {
clear.ClearSendChan(session.sendChan)
}
session.sendMutex.Unlock()
}

err := session.codec.Close()
if session.manager != nil {
session.manager.delSession(session)
}
Expand Down Expand Up @@ -91,25 +102,34 @@ func (session *Session) sendLoop() {
}
}

func (session *Session) Send(msg interface{}) (err error) {
func (session *Session) Send(msg interface{}) error {
if session.IsClosed() {
return SessionClosedError
}

if session.sendChan == nil {
return session.codec.Send(msg)
err := session.codec.Send(msg)
if err != nil {
session.Close()
}
return err
}

session.sendMutex.RLock()
select {
case session.sendChan <- msg:
session.sendMutex.RUnlock()
return nil
case <-session.closeChan:
session.sendMutex.RUnlock()
return SessionClosedError
default:
session.sendMutex.RUnlock()
session.Close()
return SessionBlockedError
}
}

func (session *Session) SendChan() chan interface{} {
return session.sendChan
}

type closeCallback struct {
Handler interface{}
Func func()
Expand Down

0 comments on commit 61bb850

Please sign in to comment.