mirror of
https://github.com/doublecmd/doublecmd.git
synced 2026-06-21 09:58:13 +00:00
FIX: sync — throttle AppProcessMessages to prevent O(n²) slowdown
AppProcessMessages was called between every single file in copy/delete loops. On Linux, each call processes all pending inotify events; if the DC file panels are watching the source/destination directories, each inotify event triggers a full panel reload (O(n) work per file copied). With ~8000 files this becomes O(n²): ~5 minutes for a trivial local copy of small files, while Windows finished in seconds. Fix: add a 50 ms gate in TFileSourceOperation.AppProcessMessages via GetTickCount64. UI stays responsive (stop button still works via the separate CheckOperationState flag path) but the GTK event queue is pumped at most every 50 ms regardless of file count.
This commit is contained in:
parent
a4c174d5ba
commit
d47e1b33ce
1 changed files with 19 additions and 1 deletions
|
|
@ -180,6 +180,13 @@ type
|
|||
FUIResponse: TFileSourceOperationUIAnswer;
|
||||
FTryAskQuestionResult: Boolean;
|
||||
|
||||
{en
|
||||
Timestamp of last AppProcessMessages call (ms). Used to throttle
|
||||
message-pumping when running on the main thread, to avoid O(n²)
|
||||
overhead from inotify-triggered panel reloads with large file sets.
|
||||
}
|
||||
FLastProcessMessagesTime: QWord;
|
||||
|
||||
{en
|
||||
Used to determine whether the operation has started or not.
|
||||
}
|
||||
|
|
@ -805,10 +812,21 @@ begin
|
|||
end;
|
||||
|
||||
function TFileSourceOperation.AppProcessMessages(CheckState: Boolean): Boolean;
|
||||
const
|
||||
// Minimum ms between GTK event-queue pumps. Prevents O(n²) panel-reload
|
||||
// overhead from inotify events when copying/deleting large file sets.
|
||||
ThrottleIntervalMs = 100;
|
||||
var
|
||||
Ticks: QWord;
|
||||
begin
|
||||
if GetCurrentThreadId = MainThreadID then
|
||||
begin
|
||||
WidgetSet.AppProcessMessages;
|
||||
Ticks := GetTickCount64;
|
||||
if Ticks - FLastProcessMessagesTime >= ThrottleIntervalMs then
|
||||
begin
|
||||
FLastProcessMessagesTime := Ticks;
|
||||
WidgetSet.AppProcessMessages;
|
||||
end;
|
||||
end;
|
||||
if CheckState then
|
||||
try
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue