github.com/devops-filetransfer/sshego@v7.0.4+incompatible/tcplock.go (about) 1 package sshego 2 3 import ( 4 "fmt" 5 "net" 6 "sync" 7 "time" 8 ) 9 10 type TcpPort struct { 11 Port int 12 Lsn net.Listener 13 mux sync.Mutex 14 } 15 16 var ErrCouldNotAquirePort = fmt.Errorf("could not acquire " + 17 "our -xport before the deadline") 18 19 func (t *TcpPort) Lock(limitMsec int) error { 20 21 t.mux.Lock() 22 addr := fmt.Sprintf("127.0.0.1:%v", t.Port) 23 t.mux.Unlock() 24 25 start := time.Now() 26 var deadline time.Time 27 if limitMsec > 0 { 28 deadline = start.Add(time.Duration(limitMsec) * time.Millisecond) 29 } 30 var lsn net.Listener 31 var err error 32 for { 33 lsn, err = net.Listen("tcp", addr) 34 if err == nil { 35 break 36 } 37 time.Sleep(10 * time.Millisecond) 38 if !deadline.IsZero() && time.Now().After(deadline) { 39 return fmt.Errorf("-xport error: could not acquire our -xport before the deadline, for -xport %v", addr) 40 } 41 } 42 t.mux.Lock() 43 t.Lsn = lsn 44 t.mux.Unlock() 45 46 return nil 47 } 48 49 func (t *TcpPort) Unlock() { 50 t.mux.Lock() 51 defer t.mux.Unlock() 52 if t.Lsn == nil { 53 return 54 } 55 t.Lsn.Close() 56 t.Lsn = nil 57 }