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.

151 lines
3.1 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
  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. // Queue the msg for output.
  44. // If the queue is full, just return false.
  45. func (p *Peer) TryQueueOut(chName String, msg Msg) bool {
  46. channel := p.Channel(chName)
  47. outQueue := channel.OutQueue()
  48. // lock & defer
  49. p.mtx.Lock(); defer p.mtx.Unlock()
  50. if p.stopped == 1 { return false }
  51. select {
  52. case outQueue <- msg:
  53. return true
  54. default: // buffer full
  55. return false
  56. }
  57. // unlock deferred
  58. }
  59. func (p *Peer) WriteTo(w io.Writer) (n int64, err error) {
  60. return p.RemoteAddress().WriteTo(w)
  61. }
  62. func (p *Peer) inHandler(chName String, inboundMsgQueue chan<- *InboundMsg) {
  63. channel := p.channels[chName]
  64. inQueue := channel.InQueue()
  65. FOR_LOOP:
  66. for {
  67. select {
  68. case <-p.quit:
  69. break FOR_LOOP
  70. case msg := <-inQueue:
  71. // send to inboundMsgQueue
  72. inboundMsg := &InboundMsg{
  73. Peer: p,
  74. Channel: channel,
  75. Time: Time{time.Now()},
  76. Msg: msg,
  77. }
  78. select {
  79. case <-p.quit:
  80. break FOR_LOOP
  81. case inboundMsgQueue <- inboundMsg:
  82. continue
  83. }
  84. }
  85. }
  86. // cleanup
  87. // (none)
  88. }
  89. func (p *Peer) outHandler(chName String) {
  90. outQueue := p.channels[chName].outQueue
  91. FOR_LOOP:
  92. for {
  93. select {
  94. case <-p.quit:
  95. break FOR_LOOP
  96. case msg := <-outQueue:
  97. // blocks until the connection is Stop'd,
  98. // which happens when this peer is Stop'd.
  99. p.conn.QueueOut(msg.Bytes)
  100. }
  101. }
  102. // cleanup
  103. // (none)
  104. }
  105. /* Channel */
  106. type Channel struct {
  107. name String
  108. inQueue chan Msg
  109. outQueue chan Msg
  110. //stats Stats
  111. }
  112. func NewChannel(name string, bufferSize int) *Channel {
  113. return &Channel{
  114. name: String(name),
  115. inQueue: make(chan Msg, bufferSize),
  116. outQueue: make(chan Msg, buffersize),
  117. }
  118. }
  119. func (c *Channel) Name() String {
  120. return c.name
  121. }
  122. func (c *Channel) InQueue() <-chan Msg {
  123. return c.inQueue
  124. }
  125. func (c *Channel) OutQueue() chan<- Msg {
  126. return c.outQueue
  127. }