I’m considering trying preemptive threads in one of my apps. That app searches for files in a selected folder, with given criteria. When searching over network shares, it’s possible for the app to hang waiting for input/output calls, even in cooperative threads, so I made a helper to handle this.
I’m now wondering whether a preemptive thread waiting for input/output calls would also block the whole app like cooperative ones do. If not, I’d get back to a single app model.
But I hardly can reproduce that on demand, so I thought I’d ask here. Has anyone already tried preemptive threading in Xojo with files access blocking (or not) the whole app?
A preemptive thread should not block the app. Since cooperative threads run on the same core as the main app, yeah they could block it as you say (although the whole point of even cooperative threads is to prevent this). But since your preemptive thread is running on a different core, it should be no issue.
But something to note - you are doing work over a network connection of some sort (TCPSocket, URLConnection or whatever you use). All those events happen on the main thread. So if something hangs with the socket, it will still hang you app.
Are you sure it is your cooperative thread blocking? I just did a quick test where I just did
Do
Loop
In the run event of a cooperative thread. App didn’t miss a beat. Maybe not a good example but…
Correct me if I am wrong, don’t thread context switches happen at loop boundaries? A better test would be something like Shell.Execute, that for sure blocks the main thread when ExecuteMode = Synchronous.
With cooperative threads, I’m indeed seeing the app hanging easily (even the GUI), accessing files from within the thread. I think it’s an I/O interrupt, and am wondering whether the whole app is supposed to block with preemptive threads as it does with cooperative.
I’m not handling the connection directly. They are smb shares (mounted volumes) and the app just iterates inside them, like any folders.
More precisely, the app usually hangs at the getattrlist instruction, as seen in Activity Monitor’s samples; it’s not specific to my app, as the Finder also suffers from that occasionally.
My issue specifically targets Input/Output interrupts (I’m not sure if it’s the exact term, but I think it’s correct), which are at a lower level. This can happen, for example, if you disconnect the network and the OS attempts to re-establish the connection, or when the server is busy, or when reading a damaged DVD (and so on). I merely know it impacts apps differently than “plain code”, but my knowledge stops here.
For cooperative threads, this used to be true (don’t know if it’s specific to the Xojo implementation, though). It’s said to be untrue for preemptive ones.
I’m actually wondering whether this would also relies on Input/Output interrupts the same way network and file systems do.
I expect so. My actual problem is that, years ago, I had re-factored my app to be split with an helper app (another, background-only, app) to avoid blocking the main app while the helper searches, and converting back to a single app is going to take some times (which I hesitate to take). So it would have been ideal to know whether someone else already saw preemptive threads blocking in such situations (which I can’t predict well, as not easily reproducible at will).
I’ll consider testing with a sample.
Thanks for your answer.
Unless you are using asynchronous file system APIs, file I/O will block the thread it is running on.
As cooperative threads run on the same CPU as the main thread, these will all be blocked at the same time.
In theory, file I/O in a preemptive thread shouldn’t block other threads but it will depend on how Xojo have implemented FolderItem.
It is also worthwhile pointing out that FolderItem can be very slow on MS-Windows across SMB shares. We found using declares + MBS functions to be much faster. I logged the following case about 5 years ago which covers part of the problem. https://tracker.xojo.com/xojoinc/xojo/-/issues/56729