Explorar o código

Fix: nil pointer reference in goroutine; cleaned up code to make
references clearer

Rod Hynes %!s(int64=11) %!d(string=hai) anos
pai
achega
7778e262a7
Modificáronse 1 ficheiros con 15 adicións e 11 borrados
  1. 15 11
      psiphon/TCPConn_windows.go

+ 15 - 11
psiphon/TCPConn_windows.go

@@ -34,7 +34,12 @@ import (
 // TODO: implement true interruptible semantics on Windows; use syscall and
 // a HANDLE similar to how TCPConn_unix uses a file descriptor?
 type interruptibleTCPSocket struct {
-	errChannel chan error
+	results chan *interruptibleDialResult
+}
+
+type interruptibleDialResult struct {
+	netConn net.Conn
+	err     error
 }
 
 func interruptibleTCPDial(addr string, config *DialConfig) (conn *TCPConn, err error) {
@@ -43,31 +48,30 @@ func interruptibleTCPDial(addr string, config *DialConfig) (conn *TCPConn, err e
 	}
 
 	conn = &TCPConn{
-		interruptible: interruptibleTCPSocket{errChannel: make(chan error, 2)},
+		interruptible: interruptibleTCPSocket{results: make(chan *interruptibleDialResult, 2)},
 		readTimeout:   config.ReadTimeout,
 		writeTimeout:  config.WriteTimeout}
 	config.PendingConns.Add(conn)
 
 	// Call the blocking Dial in a goroutine
-	var netConn net.Conn
+	results := conn.interruptible.results
 	go func() {
-		var err error
-		netConn, err = net.DialTimeout("tcp", addr, config.ConnectTimeout)
-		conn.interruptible.errChannel <- err
+		netConn, err := net.DialTimeout("tcp", addr, config.ConnectTimeout)
+		results <- &interruptibleDialResult{netConn, err}
 	}()
 
 	// Block until Dial completes (or times out) or until interrupt
-	err = <-conn.interruptible.errChannel
+	result := <-conn.interruptible.results
 	config.PendingConns.Remove(conn)
-	if err != nil {
-		return nil, ContextError(err)
+	if result.err != nil {
+		return nil, ContextError(result.err)
 	}
-	conn.Conn = netConn
+	conn.Conn = result.netConn
 
 	return conn, nil
 }
 
 func interruptibleTCPClose(interruptible interruptibleTCPSocket) error {
-	interruptible.errChannel <- errors.New("socket interrupted")
+	interruptible.results <- &interruptibleDialResult{nil, errors.New("socket interrupted")}
 	return nil
 }