Skip to content

Instantly share code, notes, and snippets.

@whyrusleeping
Created May 11, 2016 19:24
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save whyrusleeping/afa2b499fb9f7c73ff254f0df2501e23 to your computer and use it in GitHub Desktop.
Save whyrusleeping/afa2b499fb9f7c73ff254f0df2501e23 to your computer and use it in GitHub Desktop.
package main
import (
"fmt"
"net"
"os"
"time"
"github.com/hashicorp/yamux"
)
func tcppipe() (net.Conn, net.Conn) {
list, err := net.Listen("tcp", "0.0.0.0:0")
if err != nil {
panic(err)
}
con, err := net.Dial("tcp", list.Addr().String())
if err != nil {
panic(err)
}
con2, err := list.Accept()
if err != nil {
panic(err)
}
return con, con2
}
func main() {
//a, b := net.Pipe()
a, b := tcppipe() // the slight latency increase of tcp makes the bug more apparent
cfg_a := &yamux.Config{
AcceptBacklog: 16,
ConnectionWriteTimeout: time.Second * 10,
EnableKeepAlive: true,
MaxStreamWindowSize: 256 << 10,
KeepAliveInterval: time.Second * 10,
LogOutput: os.Stderr,
}
cfg_b := &yamux.Config{
AcceptBacklog: 16,
ConnectionWriteTimeout: time.Second * 10,
EnableKeepAlive: true,
MaxStreamWindowSize: 256 << 10,
KeepAliveInterval: time.Second * 10,
LogOutput: os.Stderr,
}
s, err := yamux.Server(a, cfg_a)
if err != nil {
panic(err)
}
defer s.Close()
c, err := yamux.Client(b, cfg_b)
if err != nil {
panic(err)
}
defer c.Close()
go func() {
for {
ns, err := s.OpenStream()
if err != nil {
panic(err)
}
ns.Close()
fmt.Println("opened - s")
}
}()
go func() {
for {
ns, err := c.OpenStream()
if err != nil {
panic(err)
}
ns.Close()
fmt.Println("opened - c")
}
}()
acc1 := make(chan bool)
go func() {
for {
select {
case <-acc1:
case <-time.After(time.Second):
panic("we're hung captain! ( ONE )")
}
}
}()
acc2 := make(chan bool)
go func() {
for {
select {
case <-acc2:
case <-time.After(time.Second):
panic("we're hung captain! ( TWO )")
}
}
}()
go func() {
for {
ac, err := c.AcceptStream()
if err != nil {
panic(err)
}
ac.Close()
fmt.Println("accepted - c")
acc1 <- true
}
}()
for {
ac, err := s.AcceptStream()
if err != nil {
panic(err)
}
ac.Close()
fmt.Println("accepted - s")
acc2 <- true
}
time.Sleep(time.Second * 5)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment