mirror of
https://github.com/rclone/rclone.git
synced 2024-12-13 02:33:58 +01:00
e7bd392a69
This fixes an important bug with listing that affects users with more than 500 objects in a listing operation.
37 lines
956 B
Go
37 lines
956 B
Go
// Copyright (C) 2019 Storj Labs, Inc.
|
|
// See LICENSE for copying information.
|
|
|
|
package netutil
|
|
|
|
import (
|
|
"net"
|
|
"runtime"
|
|
)
|
|
|
|
// closeTrackingConn wraps a net.Conn and keeps track of if it was closed
|
|
// or if it was leaked (and closes it if it was leaked).
|
|
type closeTrackingConn struct {
|
|
net.Conn
|
|
}
|
|
|
|
// TrackClose wraps the conn and sets a finalizer on the returned value to
|
|
// close the conn and monitor that it was leaked.
|
|
func TrackClose(conn net.Conn) net.Conn {
|
|
tracked := &closeTrackingConn{Conn: conn}
|
|
runtime.SetFinalizer(tracked, (*closeTrackingConn).finalize)
|
|
return tracked
|
|
}
|
|
|
|
// Close clears the finalizer and closes the connection.
|
|
func (c *closeTrackingConn) Close() error {
|
|
runtime.SetFinalizer(c, nil)
|
|
mon.Event("connection_closed")
|
|
return c.Conn.Close()
|
|
}
|
|
|
|
// finalize monitors that a connection was leaked and closes the connection.
|
|
func (c *closeTrackingConn) finalize() {
|
|
mon.Event("connection_leaked")
|
|
_ = c.Conn.Close()
|
|
}
|