package stat import ( "container/list" "fmt" "github.com/TransX/log" "sync" ) type TunnelStatusManager struct { mux sync.Mutex tunnelList *list.List regChan chan interface{} unregChan chan interface{} } func NewTunnelStatusManager() *TunnelStatusManager { t := new(TunnelStatusManager) t.regChan = make(chan interface{}) t.unregChan = make(chan interface{}) t.tunnelList = new(list.List) go t.chanListener() return t } func (this *TunnelStatusManager) GetRegChan() chan interface{} { return this.regChan } func (this *TunnelStatusManager) GetUnregChan() chan interface{} { return this.unregChan } func (this *TunnelStatusManager) register(t interface{}) { this.mux.Lock() defer this.mux.Unlock() this.tunnelList.PushBack(t) } func (this *TunnelStatusManager) unregister(t interface{}) { this.mux.Lock() defer this.mux.Unlock() l := this.tunnelList // log.Debug("%d tunnels before remove.", this.tunnelList.Len()) nl := new(list.List) for e := l.Front(); e != nil; e = e.Next() { if e.Value != t { nl.PushBack(e.Value) } } this.tunnelList = nl // log.Debug("%d tunnels after remove.", this.tunnelList.Len()) } func (this *TunnelStatusManager) chanListener() { for { select { case r := <-this.regChan: this.register(r) log.Debug(this.QueryStatString()) case ur := <-this.unregChan: this.unregister(ur) } } } func (this *TunnelStatusManager) QueryStatString() string { this.mux.Lock() defer this.mux.Unlock() return fmt.Sprintf("There %d tunnels running.\n", this.tunnelList.Len()) }