[Bug 39773] New: File->Open slowdown caused by desktop.ini checks
https://bugs.winehq.org/show_bug.cgi?id=39773 Bug ID: 39773 Summary: File->Open slowdown caused by desktop.ini checks Product: Wine Version: 1.8-rc2 Hardware: x86 OS: Linux Status: NEW Severity: normal Priority: P2 Component: shell32 Assignee: wine-bugs(a)winehq.org Reporter: fgouget(a)codeweavers.com Distribution: --- To reproduce this you will need two Linux machines, a Samba server and a Samba client. On the Samba server: * Create a directory with lots of subdirectories and files: mkdir smbdir cd smbdir for i in `seq 1 200`;do mkdir sub$i; done for i in `seq 1 200`;do touch file$i; done * Export smbdir through Samba. (alternatively you could export '/' and use '/usr/lib' as a replacement for smbdir) On the Samba client: * Mount the Samba share. You can either do it by adding a /etc/fstab line like: //MYSERVER/smbdir /mnt/smbdir cifs rw,username=MYLOGIN,password=MYPASSWORD,domain=MYDOMAIN 0 0 Or by starting Nautilus in GNOME, clicking on '+Other Places' -> Windows network... using GVFS. Note that in this case you'll have to work around the colon in the mount point filename (see bug 34868). * Slow down the network connection using a command like this: tc qdisc add dev eth0 root netem delay 10ms * Check the above line is effective by running: ping MYSERVER The rtt should be around 10ms. * cd /mnt/root/ wine notepad * Open the File->Open dialog, navigate to the smbdir folder exported through Samba. * BUG: The initial display will be slow and scrolling through the many subfolders will be very slow. * Change the file mask to '*.*'. * Scroll all the way to the right so only files are visible. As long as only files are visible scrolling should then be very fast! * Finally change the rtt to 0ms on the Samba server and check that the RTT is under 1ms. * Now test again notepad's File->Open dialog and everything should be reasonably fast. The problem is that whenever File->Open displays a folder in the open file dialog it checks whether it contains a desktop.ini file to display the right icon. That's not cached, thus incurring a few file lookups per folder displayed. For local file systems that's fast enough but on network shares with a non-trivial RTT the speed impact is significant. A 10+ ms RTT makes the dialog essentially unusable. Note that when displaying a filename we have everything in the cache so redisplays are lightning fast and track the mouse. Also Microsoft Office has the same problem even though it does not use the standard comdlg32 dialog (though that may depend on the Windows version being emulate). On Windows Microsoft Office suffers no slowdown in this situation. What this means is that the standard common dialog is probably the wrong level for fixing this. Hacking SHELL32_GetCustomFolderAttributeFromPath() in shell32 to just return FALSE speeds things up greatly. The display still lags a bit behind the mouse so that there may be some residual file lookups or other slowdowns but it's still night and day. -- Do not reply to this email, post in Bugzilla using the above URL to reply. You are receiving this mail because: You are watching all bug changes.
https://bugs.winehq.org/show_bug.cgi?id=39773 Alistair Leslie-Hughes <leslie_alistair(a)hotmail.com> changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |leslie_alistair(a)hotmail.com -- Do not reply to this email, post in Bugzilla using the above URL to reply. You are receiving this mail because: You are watching all bug changes.
https://bugs.winehq.org/show_bug.cgi?id=39773 joaopa <jeremielapuree(a)yahoo.fr> changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |jeremielapuree(a)yahoo.fr --- Comment #1 from joaopa <jeremielapuree(a)yahoo.fr> --- Does the bug still occur with wine-5.22? -- Do not reply to this email, post in Bugzilla using the above URL to reply. You are receiving this mail because: You are watching all bug changes.
http://bugs.winehq.org/show_bug.cgi?id=39773 TOP <kellnerp@earthlink.net> changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |kellnerp@earthlink.net --- Comment #2 from TOP <kellnerp@earthlink.net> --- Comment for https://bugs.winehq.org/show_bug.cgi?id=39773 --- Ran into this same issue (uncached `desktop.ini` lookup in `SHELL32_GetCustomFolderAttributeFromPath()`) via a different real-world trigger than the original report, and did a fairly deep investigation that I think adds useful evidence. Posting a summary; happy to attach the reproduction source files if useful. **Real-world trigger:** Insta360 Studio 2022 (Qt5-based app running under Wine), when shift-click range-selecting a large sequence of files (~1000 interval/timelapse photos) in its file browser. No network share needed to reproduce the severity — a local filesystem with a moderately deep path (~10 components) and a large selection is enough to turn this into a multi-minute apparent hang requiring force-quit. **Confirmed mechanism (two independent live backtraces via `winedbg --gdb` on the hung process):** Main UI thread found blocked in `NtCreateFile`, with the following call chain (frame numbers as captured; some `SHELL32_BindToChild` recursion frames omitted for brevity): ``` NtCreateFile -> CreateFileW dlls/kernelbase/file.c:873 -> PROFILE_Open dlls/kernel32/profile.c:764 -> GetPrivateProfileStringW dlls/kernel32/profile.c:1422 -> SHELL32_GetCustomFolderAttributeFromPath dlls/shell32/shlfolder.c:75 -> SHELL32_BindToChild (recursing, once per path component) -> ShellItem_get_parent_shellfolder dlls/shell32/shellitem.c:165 -> ShellItem_GetAttributes dlls/shell32/shellitem.c:285 -> [caller in platforms/qwindows.dll -- Qt5 platform plugin] ``` Confirmed twice, independently, on different sessions/paths -- same mechanism both times. **Source-level confirmation of why this compounds so badly:** in `dlls/shell32/shlview.c`, `LV_AddItem()` inserts list items with: ```c lvItem.pszText = LPSTR_TEXTCALLBACKW; /* get text on a callback basis */ lvItem.iImage = I_IMAGECALLBACK; /* get the image on a callback basis */ ``` i.e. the ListView is populated in owner-data/callback mode. It does not hold display data -- it re-requests it via `LVN_GETDISPINFO` every time it needs to *show* an item (initial paint, scroll, selection-state change, any redraw). Each of those callbacks resolves through the shell folder, hitting the uncached `desktop.ini` walk again. This means the real-world cost isn't "N files x path-depth" as a single pass -- it's that multiplied again by however many times the UI redraws each visible item during the operation. **Quantitative confirmation**, using a 1000-file/10-level-deep synthetic test tree (fully synthetic, reproducible without Insta360): | Test | Per-item cost | Notes | |---|---|---| | Headless console app, single `IShellItem::GetAttributes()` call per file, no UI | 2.1 ms | Baseline: raw uncached-lookup cost only | | Custom listview replicating shlview.c's exact `LPSTR_TEXTCALLBACKW` pattern, `strace`'d | ~399 `openat` syscalls/file | Manual real interaction (shift-click), not automated | | Real `GetOpenFileNameW()` dialog (Wine's actual comdlg32/shell32), manual shift-click | ~76 ms/item | Two independently-built repro programs converge on ~76-77ms/item and similar syscall-count order of magnitude | | Real Insta360 Studio, live process, `strace`'d during actual hang | ~534 `openat` syscalls/file, ~750ms/item wall time | 947-file real selection | The call-count order of magnitude (mid-hundreds of opens per file) is consistent across three independently-measured sources: the real app, a minimal custom owner-data listview, and the real Wine common dialog. The residual gap between synthetic repro wall-time (~76ms/item) and the real app (~750ms/item) is most likely wineserver round-trip contention from Studio's ~80 background threads competing for the same serialized socket during selection -- not reproducible in an isolated single-process test by design, and not needed to explain the core mechanism or its severity. **Confirms this comment's suggested fix (from the original report) still applies and is the right fix:** caching `SHELL32_GetCustomFolderAttributeFromPath()`'s result per directory (rather than returning FALSE unconditionally, which would break legitimate custom-folder-icon support) would collapse the repeated-lookup cost to one real check per unique directory for the lifetime of a shell operation, regardless of how many times the owner-data listview re-queries display info per item. This matches how native Windows Explorer behaves (per the original report: "when displaying a filename we have everything in the cache so redisplays are lightning fast"). Still reproducible on current Wine (tested on 11.0), a decade after the original report -- this remains an open, real-world-impacting issue. -- Do not reply to this email, post in Bugzilla using the above URL to reply. You are receiving this mail because: You are watching all bug changes.
http://bugs.winehq.org/show_bug.cgi?id=39773 Ken Sharp <imwellcushtymelike@gmail.com> changed: What |Removed |Added ---------------------------------------------------------------------------- Keywords| |performance, source -- Do not reply to this email, post in Bugzilla using the above URL to reply. You are receiving this mail because: You are watching all bug changes.
http://bugs.winehq.org/show_bug.cgi?id=39773 --- Comment #3 from Ken Sharp <imwellcushtymelike@gmail.com> --- *** Bug 60295 has been marked as a duplicate of this bug. *** -- Do not reply to this email, post in Bugzilla using the above URL to reply. You are receiving this mail because: You are watching all bug changes.
participants (3)
-
wine-bugs@winehq.org -
WineHQ Bugzilla -
WineHQ Bugzilla