func NewTransport(frame trace.Frame, sub *codec.Transport) *Transport {
	t := &Transport{
		frame:  frame,
		sub:    sub,
		Dialer: NewDialer(frame.Refine("dialer"), sub),
	}
	frame.Bind(t)
	return t
}
func NewListener(frame trace.Frame, sub *codec.Listener) *Listener {
	l := &Listener{frame: frame, sub: sub, ach: make(chan *Conn)}
	frame.Bind(l)
	go func() {
		for {
			NewAcceptBridge(l.frame.Refine("accept"), l, l.sub.Accept())
		}
	}()
	return l
}
Example #3
0
// NewBuffer creates a new buffer with limit m.
func NewBuffer(frame trace.Frame, m int) *Buffer {
	b := &Buffer{
		wch: make(chan struct{}, m+1), // +1 for the final EOF, so it does not block
		// The capacity of rch is chosen so that writers to rch will never block.
		rch: make(chan struct{}, 4*m+2),
	}
	frame.Bind(b)
	b.Frame = frame
	for i := 0; i < m; i++ {
		b.wch <- struct{}{}
	}
	return b
}
Example #4
0
func (a *Conn) Start(frame trace.Frame, id chainID, addr net.Addr, linker linker, scrb func()) {
	frame.Bind(a)
	a.frame = frame
	a.scrb = scrb
	a.id = id
	a.addr = addr
	a.linker = linker
	a.cascade = MakeCascade(frame)
	// A buffer size 1 on rch, helps remove a deadlock in the TestConn.
	// Essentially it ensures that Read and Write (on two ends of a
	// connection) cannot deadlock each other when a successful Write also
	// requires a stitch. We throw in a couple of extra buffer spaces to
	// prevent any potential deadlock between Read and Kill.
	a.rch = make(chan interface{}, 3)
	a.kch = make(chan struct{})
	go a.readLoop()
}