Repository: syncthing/syncthing (language: go)

Issue:
setLowPriority should not increase process priority when already lower (in Windows)
Syncthing, with `setLowPriority` set to `true`, always sets its child process priority to `Below normal`, even if the parent priority is already lower than that.

To reproduce in Windows command line:

```
start /low syncthing.exe
```

Even though the parent process priority is `Idle`, the child process priority gets changed to `Below normal`.

![image](https://user-images.githubusercontent.com/5626656/80912106-afe60980-8d75-11ea-9670-41ad43e497d3.png)

On the other hand, with `setLowPriority` set to `false`, the child process priority remains `Idle`, following its parent priority.

![image](https://user-images.githubusercontent.com/5626656/80911954-a90ac700-8d74-11ea-9879-83e2419afef7.png)

I would argue that `setLowPriority` should not make Syncthing change its priority to a higher value than the one already defined on runtime.

### Version Information

Syncthing Version: v1.4.2
OS Version: Windows 10 Enterprise 1607 LTSB




Discussion / hints:
It would also be nice if there was an command-line option that could prevent this as a default so that the calling process could decide and not get overridden: https://github.com/syncthing/syncthing/issues/8087
FWIW, the Syncthing Windows Setup package (https://github.com/Bill-Stewart/SyncthingWindowsSetup) automatically configures `<setLowPriority>` to `false` at the end of installation (the service and script launchers specify the process priority).

Fix patch:
diff --git a/lib/osutil/lowprio_windows.go b/lib/osutil/lowprio_windows.go
index 1efee52b2c8..3cf97aa1ae7 100644
--- a/lib/osutil/lowprio_windows.go
+++ b/lib/osutil/lowprio_windows.go
@@ -21,6 +21,11 @@ func SetLowPriority() error {
 	}
 	defer windows.CloseHandle(handle)
 
+	if cur, err := windows.GetPriorityClass(handle); err == nil && (cur == windows.IDLE_PRIORITY_CLASS || cur == windows.BELOW_NORMAL_PRIORITY_CLASS) {
+		// We're done here.
+		return nil
+	}
+
 	if err := windows.SetPriorityClass(handle, windows.BELOW_NORMAL_PRIORITY_CLASS); err != nil {
 		return fmt.Errorf("set priority class: %w", err)
 	}


Test patch: