-
Notifications
You must be signed in to change notification settings - Fork 41
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
feat: Add a pure-Rust connection to x11rb-async #797
Conversation
Codecov ReportPatch coverage has no change and project coverage change:
Additional details and impacted files@@ Coverage Diff @@
## master #797 +/- ##
==========================================
- Coverage 12.46% 12.28% -0.19%
==========================================
Files 180 183 +3
Lines 133169 135277 +2108
==========================================
+ Hits 16603 16615 +12
- Misses 116566 118662 +2096
Flags with carried forward coverage won't be shown. Click here to find out more.
... and 34 files with indirect coverage changes Help us with your feedback. Take ten seconds to tell us how you rate us. Have a feature suggestion? Share it here. ☔ View full report in Codecov by Sentry. |
Sigh... Can we come back when the Rust ecosystem becomes mature and stops breaking stuff all the time? As far as I can tell, the PR that introduced that picked that version just because they want to eventually use features from that version. Not because they already require this. Shall we pin the dependency to 0.5.0? 🙈 |
Google suggests that the appveyor failure is transient. However, a retry of the build did not make it go away. Yay. 🙈
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
IIRC the biggest open question here is to do the reading. Right now this implements "automatic reading" in x11rb-style, but at the same time also offers the possibility to do that in an extra task. Right now I do not see the value in providing both and the "automatic reading"-code seems to have some races.
Besides that, I think the other comments are minor and/or clear.
where | ||
S: Send + Sync, | ||
{ | ||
let mut mrl = match self.max_request_bytes.try_lock() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why not lock()
? Whatever this is, it might need a comment. And even then, it seems incorrect: The lock guard is held across an await point in the case of Unknown
, so if two large requests are sent at once, one of them could fail incorrectly with a "too large request" error.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The mutex being locked is taken as a signal that another part of the program is using the current request to find out the maximum bytes. I've added a comment clarifying this.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, but couldn't it be another task that holds this mutex? I don't think using the mutex like this actually works.
So... how does x11rb do it? RustConnection::maximum_request_bytes()
unconditionally locks the mutex. This would not work if the current thread already holds the mutex.
Also, the code in compute_length_field
only calls maximum_request_bytes()
when the request length does not fit into an u16. That feels a bit like a bug (couldn't an X11 server have a maximum request length smaller than 2^18?), but that should mean that all requests from the BigRequests extension do not actually hit this code here...
Personally, I'd prefer to just have a future that's spawned at |
f402e31
to
0ff7602
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks! Let's see what happens.
I'll merge this so that we do not end in endless discussions. I'll write down the remaining points for later:
- I am not yet convinced the
try_lock()
for the maximum request length actually works correctly. A "too large request" error is possible just because another task currently holds the mutex. - Implementing
Default
forx11rb-protocol::connection::Connection
.
Complements #790 by adding a connection type to
x11rb-async
that connects to the X11 server using pure Rust. I useasync-io
for handling I/O andasync-lock
for locking shared types.By the way, do we also want to have an async XCB-based connection as well? It's possible, see bread-graphics/whitebreadx#1, but it would need blocking I/O anyways so the official direction might need to be "just throw an
XCBConnection
into aBlockingConnection
.