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.

187 lines
3.8 KiB

11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
  1. package peer
  2. import (
  3. . "github.com/tendermint/tendermint/binary"
  4. "sync/atomic"
  5. "sync"
  6. "io"
  7. "time"
  8. )
  9. /* Peer */
  10. type Peer struct {
  11. outgoing bool
  12. conn *Connection
  13. channels map[String]*Channel
  14. mtx sync.Mutex
  15. quit chan struct{}
  16. stopped uint32
  17. }
  18. func (p *Peer) Start(peerInQueues map[String]chan *InboundMsg ) {
  19. for chName, _ := range p.channels {
  20. go p.inHandler(chName, peerInQueues[chName])
  21. go p.outHandler(chName)
  22. }
  23. }
  24. func (p *Peer) Stop() {
  25. // lock
  26. p.mtx.Lock()
  27. if atomic.CompareAndSwapUint32(&p.stopped, 0, 1) {
  28. close(p.quit)
  29. p.conn.Stop()
  30. }
  31. p.mtx.Unlock()
  32. // unlock
  33. }
  34. func (p *Peer) LocalAddress() *NetAddress {
  35. return p.conn.LocalAddress()
  36. }
  37. func (p *Peer) RemoteAddress() *NetAddress {
  38. return p.conn.RemoteAddress()
  39. }
  40. func (p *Peer) Channel(chName String) *Channel {
  41. return p.channels[chName]
  42. }
  43. // If msg isn't already in the peer's filter, then
  44. // queue the msg for output.
  45. // If the queue is full, just return false.
  46. func (p *Peer) TryQueueOut(chName String, msg Msg) bool {
  47. channel := p.Channel(chName)
  48. outQueue := channel.OutQueue()
  49. // just return if already in filter
  50. if channel.Filter().Has(msg) {
  51. return true
  52. }
  53. // lock & defer
  54. p.mtx.Lock(); defer p.mtx.Unlock()
  55. if p.stopped == 1 { return false }
  56. select {
  57. case outQueue <- msg:
  58. return true
  59. default: // buffer full
  60. return false
  61. }
  62. // unlock deferred
  63. }
  64. func (p *Peer) WriteTo(w io.Writer) (n int64, err error) {
  65. return p.RemoteAddress().WriteTo(w)
  66. }
  67. func (p *Peer) inHandler(chName String, inboundMsgQueue chan<- *InboundMsg) {
  68. channel := p.channels[chName]
  69. inQueue := channel.InQueue()
  70. FOR_LOOP:
  71. for {
  72. select {
  73. case <-p.quit:
  74. break FOR_LOOP
  75. case msg := <-inQueue:
  76. // add to channel filter
  77. channel.Filter().Add(msg)
  78. // send to inboundMsgQueue
  79. inboundMsg := &InboundMsg{
  80. Peer: p,
  81. Channel: channel,
  82. Time: Time{time.Now()},
  83. Msg: msg,
  84. }
  85. select {
  86. case <-p.quit:
  87. break FOR_LOOP
  88. case inboundMsgQueue <- inboundMsg:
  89. continue
  90. }
  91. }
  92. }
  93. // cleanup
  94. // (none)
  95. }
  96. func (p *Peer) outHandler(chName String) {
  97. outQueue := p.channels[chName].outQueue
  98. FOR_LOOP:
  99. for {
  100. select {
  101. case <-p.quit:
  102. break FOR_LOOP
  103. case msg := <-outQueue:
  104. // blocks until the connection is Stop'd,
  105. // which happens when this peer is Stop'd.
  106. p.conn.QueueOut(msg.Bytes)
  107. }
  108. }
  109. // cleanup
  110. // (none)
  111. }
  112. /* Channel */
  113. type Channel struct {
  114. name String
  115. mtx sync.Mutex
  116. filter Filter
  117. inQueue chan Msg
  118. outQueue chan Msg
  119. //stats Stats
  120. }
  121. func NewChannel(name String, filter Filter, in, out chan Msg) *Channel {
  122. return &Channel{
  123. name: name,
  124. filter: filter,
  125. inQueue: in,
  126. outQueue: out,
  127. }
  128. }
  129. func (c *Channel) Name() String {
  130. return c.name
  131. }
  132. func (c *Channel) InQueue() <-chan Msg {
  133. return c.inQueue
  134. }
  135. func (c *Channel) OutQueue() chan<- Msg {
  136. return c.outQueue
  137. }
  138. func (c *Channel) Add(msg Msg) {
  139. c.Filter().Add(msg)
  140. }
  141. func (c *Channel) Has(msg Msg) bool {
  142. return c.Filter().Has(msg)
  143. }
  144. func (c *Channel) Filter() Filter {
  145. // lock & defer
  146. c.mtx.Lock(); defer c.mtx.Unlock()
  147. return c.filter
  148. // unlock deferred
  149. }
  150. func (c *Channel) UpdateFilter(filter Filter) {
  151. // lock
  152. c.mtx.Lock()
  153. c.filter = filter
  154. c.mtx.Unlock()
  155. // unlock
  156. }