github.com/jmigpin/editor@v1.6.0/util/chanutil/chanq.go (about) 1 package chanutil 2 3 import ( 4 "container/list" 5 ) 6 7 // Flexible channel queue (no fixed length). Note: consider using syncutil.* instead. 8 type ChanQ struct { 9 q list.List 10 in, out chan interface{} 11 } 12 13 func NewChanQ(inSize, outSize int) *ChanQ { 14 ch := &ChanQ{} 15 ch.in = make(chan interface{}, inSize) 16 ch.out = make(chan interface{}, outSize) 17 go ch.loop() 18 return ch 19 } 20 21 func (ch *ChanQ) In() chan<- interface{} { 22 return ch.in 23 } 24 25 func (ch *ChanQ) Out() <-chan interface{} { 26 return ch.out 27 } 28 29 func (ch *ChanQ) loop() { 30 var next interface{} 31 var out chan<- interface{} 32 for { 33 select { 34 case v := <-ch.in: 35 if next == nil { 36 next = v 37 out = ch.out 38 } else { 39 ch.q.PushBack(v) 40 } 41 case out <- next: 42 elem := ch.q.Front() 43 if elem == nil { 44 next = nil 45 out = nil 46 } else { 47 next = elem.Value 48 out = ch.out 49 ch.q.Remove(elem) 50 } 51 } 52 } 53 }