mirror of
https://github.com/rclone/rclone.git
synced 2024-11-07 17:14:44 +01:00
operations: fix deadlock when using lsd/ls with --progress - Fixes #7102
The --progress flag overrides operations.SyncPrintf in order to do its magic on stdout without interfering with other output. Before this change the syncFprintf routine in operations (which is used to print all output to stdout) was taking the operations.StdoutMutex and the printProgress function in the --progress routine was also attempting to take the same mutex causing a deadlock. This patch fixes the problem by moving the locking from the syncFprintf function to SyncPrintf. It is then up to the function overriding this to lock the StdoutMutex. This ensures the StdoutMutex can never cause a deadlock.
This commit is contained in:
parent
07133b892d
commit
22a14a8c98
@ -926,10 +926,15 @@ func ListFn(ctx context.Context, f fs.Fs, fn func(fs.Object)) error {
|
|||||||
// StdoutMutex mutex for synchronized output on stdout
|
// StdoutMutex mutex for synchronized output on stdout
|
||||||
var StdoutMutex sync.Mutex
|
var StdoutMutex sync.Mutex
|
||||||
|
|
||||||
// SyncPrintf is a global var holding the Printf function used in syncFprintf so that it can be overridden
|
// SyncPrintf is a global var holding the Printf function so that it
|
||||||
// Note, despite name, does not provide sync and should not be called directly
|
// can be overridden.
|
||||||
// Call syncFprintf, which provides sync
|
//
|
||||||
|
// This writes to stdout holding the StdoutMutex. If you are going to
|
||||||
|
// override it and write to os.Stdout then you should hold the
|
||||||
|
// StdoutMutex too.
|
||||||
var SyncPrintf = func(format string, a ...interface{}) {
|
var SyncPrintf = func(format string, a ...interface{}) {
|
||||||
|
StdoutMutex.Lock()
|
||||||
|
defer StdoutMutex.Unlock()
|
||||||
fmt.Printf(format, a...)
|
fmt.Printf(format, a...)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -937,14 +942,13 @@ var SyncPrintf = func(format string, a ...interface{}) {
|
|||||||
//
|
//
|
||||||
// Ignores errors from Fprintf.
|
// Ignores errors from Fprintf.
|
||||||
//
|
//
|
||||||
// Updated to print to terminal if no writer is defined
|
// Prints to stdout if w is nil
|
||||||
// This special behavior is used to allow easier replacement of the print to terminal code by progress
|
|
||||||
func syncFprintf(w io.Writer, format string, a ...interface{}) {
|
func syncFprintf(w io.Writer, format string, a ...interface{}) {
|
||||||
StdoutMutex.Lock()
|
|
||||||
defer StdoutMutex.Unlock()
|
|
||||||
if w == nil || w == os.Stdout {
|
if w == nil || w == os.Stdout {
|
||||||
SyncPrintf(format, a...)
|
SyncPrintf(format, a...)
|
||||||
} else {
|
} else {
|
||||||
|
StdoutMutex.Lock()
|
||||||
|
defer StdoutMutex.Unlock()
|
||||||
_, _ = fmt.Fprintf(w, format, a...)
|
_, _ = fmt.Fprintf(w, format, a...)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user