Fix race condition in CopyFrom
In case of an error it was possible for the goroutine that builds the copy stream to still be running after CopyFrom returned. Since that goroutine uses the connections ConnInfo data types to encode the copy data it was possible for those types to be concurrently used in an unsafe fashion. CopyFrom will no longer return until that goroutine has completed.
This commit is contained in:
@@ -75,8 +75,11 @@ func (ct *copyFrom) run(ctx context.Context) (int64, error) {
|
||||
}
|
||||
|
||||
r, w := io.Pipe()
|
||||
doneChan := make(chan struct{})
|
||||
|
||||
go func() {
|
||||
defer close(doneChan)
|
||||
|
||||
// Purposely NOT using defer w.Close(). See https://github.com/golang/go/issues/24283.
|
||||
buf := ct.conn.wbuf
|
||||
|
||||
@@ -114,6 +117,9 @@ func (ct *copyFrom) run(ctx context.Context) (int64, error) {
|
||||
|
||||
commandTag, err := ct.conn.pgConn.CopyFrom(ctx, r, fmt.Sprintf("copy %s ( %s ) from stdin binary;", quotedTableName, quotedColumnNames))
|
||||
|
||||
r.Close()
|
||||
<-doneChan
|
||||
|
||||
return commandTag.RowsAffected(), err
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user