go语言TCPConn.Close()方法处理不当引发的bug

Time: 十月 24, 2012
Category: Programming practices

今天服务器引发了一个很罕见的bug。原因是因为TCPConn在Close的时候,把fd给清空掉了,如下:

// Close closes the TCP connection.
func (c *TCPConn) Close() error {
	if !c.ok() {
		return syscall.EINVAL
	}
	err := c.fd.Close()
	c.fd = nil
	return err
}

而TCPConn是经常在多个goroutine里同时使用的。

// Read implements the Conn Read method.
func (c *TCPConn) Read(b []byte) (n int, err error) {
	if !c.ok() {
		return 0, syscall.EINVAL
	}
	return c.fd.Read(b)
}

这样就很有可能当某个goroutine,判断!c.ok(),为真,然后尝试读取数据时。注意,这个过程,中间,if语句之后和Read()数据之前,很可能TCPConn已经被关闭,fd被置为nil了,引发panic

go1版本有这个问题。新版已经fix了。不过我还觉得蛮奇怪的,想不清楚为什么作者要这么写。。。

Leave a Comment