Official cwtch.im peer and server implementations. https://cwtch.im
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

73 lines
1.5KB

  1. package bridge
  2. /* Todo: When go generics ships, refactor this and event.infiniteChannel into one */
  3. // InfiniteChannel implements the Channel interface with an infinite buffer between the input and the output.
  4. type InfiniteChannel struct {
  5. input, output chan interface{}
  6. length chan int
  7. buffer *InfiniteQueue
  8. }
  9. func newInfiniteChannel() *InfiniteChannel {
  10. ch := &InfiniteChannel{
  11. input: make(chan interface{}),
  12. output: make(chan interface{}),
  13. length: make(chan int),
  14. buffer: newInfiniteQueue(),
  15. }
  16. go ch.infiniteBuffer()
  17. return ch
  18. }
  19. // In returns the input channel
  20. func (ch *InfiniteChannel) In() chan<- interface{} {
  21. return ch.input
  22. }
  23. // Out returns the output channel
  24. func (ch *InfiniteChannel) Out() <-chan interface{} {
  25. return ch.output
  26. }
  27. // Len returns the length of items in queue
  28. func (ch *InfiniteChannel) Len() int {
  29. return <-ch.length
  30. }
  31. // Close closes the InfiniteChanel
  32. func (ch *InfiniteChannel) Close() {
  33. close(ch.input)
  34. }
  35. func (ch *InfiniteChannel) infiniteBuffer() {
  36. var input, output chan interface{}
  37. var next interface{}
  38. input = ch.input
  39. for input != nil || output != nil {
  40. select {
  41. case elem, open := <-input:
  42. if open {
  43. ch.buffer.Add(elem)
  44. } else {
  45. input = nil
  46. }
  47. case output <- next:
  48. ch.buffer.Remove()
  49. case ch.length <- ch.buffer.Length():
  50. }
  51. if ch.buffer.Length() > 0 {
  52. output = ch.output
  53. next = ch.buffer.Peek()
  54. } else {
  55. output = nil
  56. next = nil
  57. }
  58. }
  59. close(ch.output)
  60. close(ch.length)
  61. }