github.com/keybase/client/go@v0.0.0-20240309051027-028f7c731f8b/kbfs/libkbfs/channels.go (about) 1 // Copyright 2017 Keybase Inc. All rights reserved. 2 // Use of this source code is governed by a BSD 3 // license that can be found in the LICENSE file. 4 5 package libkbfs 6 7 import ( 8 "sync" 9 10 "github.com/eapache/channels" 11 ) 12 13 const ( 14 defaultInfiniteBufferSize int = 0 15 ) 16 17 // InfiniteChannelWrapper is a wrapper to allow us to select on sending to an 18 // infinite channel without fearing a panic when we Close() it. 19 type InfiniteChannelWrapper struct { 20 *channels.InfiniteChannel 21 input chan interface{} 22 shutdownOnce sync.Once 23 shutdownCh chan struct{} 24 } 25 26 var _ channels.Channel = (*InfiniteChannelWrapper)(nil) 27 28 // NewInfiniteChannelWrapper returns a wrapper around a new infinite 29 // channel. 30 func NewInfiniteChannelWrapper() *InfiniteChannelWrapper { 31 ch := &InfiniteChannelWrapper{ 32 InfiniteChannel: channels.NewInfiniteChannel(), 33 input: make(chan interface{}, defaultInfiniteBufferSize), 34 shutdownCh: make(chan struct{}), 35 } 36 go ch.run() 37 return ch 38 } 39 40 func (ch *InfiniteChannelWrapper) run() { 41 for { 42 select { 43 case next := <-ch.input: 44 ch.InfiniteChannel.In() <- next 45 case <-ch.shutdownCh: 46 ch.InfiniteChannel.Close() 47 return 48 } 49 } 50 } 51 52 // In returns the input channel for this infinite channel. 53 func (ch *InfiniteChannelWrapper) In() chan<- interface{} { 54 return ch.input 55 } 56 57 // Close shuts down this infinite channel. 58 func (ch *InfiniteChannelWrapper) Close() { 59 ch.shutdownOnce.Do(func() { 60 close(ch.shutdownCh) 61 }) 62 }