New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[feature] Constraining a future to a specific OS thread #1583
Comments
Winit requires owning the event loop; as a result, running tokio on winit's thread doesn't make a lot of sense. You could still potentially use futures; I believe @Osspial is experimenting with adapting the core event loop to be futures-driven. Those futures could freely communicate with other tokio-owned threads, if desired. |
This question comes up a bunch so I’m hoping to get a guide put together. It does not need to be extensive. |
Relevant: https://github.com/osspial/winit-async |
I believe that #1733 could potentially be used to constrain a future to run on the current thread. However, I don't think that would actually solve the winit problem? |
@hawkw Since writing |
Does this include applications that are "non-responsive" (non-native gui, like games which render every 16 ms)? In the case of games, the standard solution appears to be pushing window events onto a channel for the rest of the system to handle. Do you have the long story perhaps? |
@BourgondAries I suppose there's a bit of ambiguity around the term "responsive" in GUI development, heh. "Real-time applications" is probably a more accurate term for this purpose. Anyhow, I mean applications that have to (or really should) respond to user input immediately, and I include non-native GUI and games in that category. In terms of how rendering interacts with the threading system, games are a bit more lenient than desktop apps - desktop apps absolutely need to process redraw requests in the main thread so that the OS delays presenting until a frame is ready, which is necessary to achieve smooth window resizing. I believe using that model also nets some latency wins, though I haven't tested that personally. Also, I mentioned events that need to modify a pointed-to value. The textbook example of this is I'll note that Winit's need for exclusive control over its event loop doesn't preclude using a thread pool within the larger application structure - indeed, driving a Tokio executor through a secondary thread, having a Rayon thread pool for speeding up calculations, or manually managing data processing through secondary threads is going to be a good idea in quite a lot of cases. It's just that Winit needs precise control over its thread, because the platform APIs we wrap demand precise control. |
I think rather than the presence of an executor being unacceptable, that simply means that winit-async needs to be an executor, which is no surprise at all. What changes to the standard API do you see as necessary to accomplish this? It seems like it should work fine as-is to me. |
I don't think we will add an explicit API to pin a future to an OS thread. There already are ways to do this. For example, you could run your own current-thread runtime on that OS thread. Due to the lack of activity, I am going to close this issue. Please comment if this is incorrect. |
The Problem
Some mechanisms are closely tied to drivers or hardware events and require us to run said thing in a single thread.
An example of this is OpenGL. You first create something called an OpenGL context, which is tied to the thread it is created in. Then, you must only draw from that specific thread. Iirc the reason for this limitation is driver synchronization happening behind the scenes. This would be racy if OpenGL calls were invoked from several threads.
Another example is the
winit
crate, specifically on iOS. It uses cocoa as a back-end and this system has the limitation that only the main thread must handle input events. Doing otherwise would be an error.What could be useful
It would be useful to constrain a future (and all its spawned children) to a specific OS thread. For instance through the following API:
Why is it useful?
It allows for
async
winit and OpenGLawait
s without causing low-level problems for drivers and/or hardware, allowing the thread to steal other tasks as long aswinit
,OpenGL
, or anything else constrained to that thread is blocking.The text was updated successfully, but these errors were encountered: