mutex protected close

pull/432/head v2.22.1
Darien Raymond 2017-04-13 20:14:07 +02:00
parent c9f661f018
commit 81d840699a
No known key found for this signature in database
GPG Key ID: 7251FFA14BB18169
3 changed files with 35 additions and 14 deletions

View File

@ -121,13 +121,12 @@ func (m *Client) monitor() {
for { for {
select { select {
case <-m.ctx.Done(): case <-m.ctx.Done():
m.sessionManager.Close()
m.inboundRay.InboundInput().Close() m.inboundRay.InboundInput().Close()
m.inboundRay.InboundOutput().CloseError() m.inboundRay.InboundOutput().CloseError()
return return
case <-time.After(time.Second * 6): case <-time.After(time.Second * 6):
size := m.sessionManager.Size() size := m.sessionManager.Size()
if size == 0 { if size == 0 && m.sessionManager.CloseIfNoSession() {
m.cancel() m.cancel()
} }
} }
@ -169,12 +168,12 @@ func (m *Client) Dispatch(ctx context.Context, outboundRay ray.OutboundRay) bool
default: default:
} }
s := &Session{ s := m.sessionManager.Allocate()
input: outboundRay.OutboundInput(), if s == nil {
output: outboundRay.OutboundOutput(), return false
parent: m.sessionManager,
} }
m.sessionManager.Allocate(s) s.input = outboundRay.OutboundInput()
s.output = outboundRay.OutboundOutput()
go fetchInput(ctx, s, m.inboundRay.InboundInput()) go fetchInput(ctx, s, m.inboundRay.InboundInput())
return true return true
} }

View File

@ -10,6 +10,7 @@ type SessionManager struct {
sync.RWMutex sync.RWMutex
count uint16 count uint16
sessions map[uint16]*Session sessions map[uint16]*Session
closed bool
} }
func NewSessionManager() *SessionManager { func NewSessionManager() *SessionManager {
@ -26,13 +27,21 @@ func (m *SessionManager) Size() int {
return len(m.sessions) return len(m.sessions)
} }
func (m *SessionManager) Allocate(s *Session) { func (m *SessionManager) Allocate() *Session {
m.Lock() m.Lock()
defer m.Unlock() defer m.Unlock()
if m.closed {
return nil
}
m.count++ m.count++
s.ID = m.count s := &Session{
ID: m.count,
parent: m,
}
m.sessions[s.ID] = s m.sessions[s.ID] = s
return s
} }
func (m *SessionManager) Add(s *Session) { func (m *SessionManager) Add(s *Session) {
@ -53,17 +62,32 @@ func (m *SessionManager) Get(id uint16) (*Session, bool) {
m.RLock() m.RLock()
defer m.RUnlock() defer m.RUnlock()
if m.closed {
return nil, false
}
s, found := m.sessions[id] s, found := m.sessions[id]
return s, found return s, found
} }
func (m *SessionManager) Close() { func (m *SessionManager) CloseIfNoSession() bool {
m.RLock() m.RLock()
defer m.RUnlock() defer m.RUnlock()
if len(m.sessions) == 0 {
return false
}
m.closed = true
for _, s := range m.sessions { for _, s := range m.sessions {
s.input.CloseError()
s.output.CloseError() s.output.CloseError()
} }
m.sessions = make(map[uint16]*Session)
return true
} }
type Session struct { type Session struct {

View File

@ -12,12 +12,10 @@ func TestSessionManagerAdd(t *testing.T) {
m := NewSessionManager() m := NewSessionManager()
s := &Session{} s := m.Allocate()
m.Allocate(s)
assert.Uint16(s.ID).Equals(1) assert.Uint16(s.ID).Equals(1)
s = &Session{} s = m.Allocate()
m.Allocate(s)
assert.Uint16(s.ID).Equals(2) assert.Uint16(s.ID).Equals(2)
s = &Session{ s = &Session{