Skip to content
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

Add RAII resource wrappers #620

Merged
merged 6 commits into from
Jun 5, 2021
Merged

Add RAII resource wrappers #620

merged 6 commits into from
Jun 5, 2021

Conversation

psychon
Copy link
Owner

@psychon psychon commented Jun 4, 2021

This PR implements #78 for the core protocol: This adds e.g. x11rb::wrapper::WindowWrapper which, well, wraps a window ID (u32). In its Drop implementation, this calls destroy_window, thus preventing "window leaks".

I am not sure how much I really like this, but here it is in the form of the PR.

Also, there is way too much hand-written code in this PR. I guess I'd prefer if the code generator generated the necessary code for these wrappers. But today is not the day for that...

This commits adds structs that e.g. wrap a window. When this struct is
dropped, the contained window is destroyed.

Such a wrapper is added for each kind of resource in the core protocol.
Extensions are not (yet?) handled.

Implements-most-of: #78
Signed-off-by: Uli Schlachter <psychon@znc.in>
Signed-off-by: Uli Schlachter <psychon@znc.in>
Signed-off-by: Uli Schlachter <psychon@znc.in>
Signed-off-by: Uli Schlachter <psychon@znc.in>
Signed-off-by: Uli Schlachter <psychon@znc.in>
@eduardosm
Copy link
Collaborator

I'm not sure how this will scale for large projects, where XIDs might be stored in structs. Those structs would need have a connection lifetime parameter. Additionally, the same struct wouldn't be able to own both the connection and a wrapped XID, because it would lead to self-references.

Additionally, I'm not sure I'm happy with sending data over a socket inside a drop, because drop can be called during a panic unwind (in that situation, you probably don't care about protocol state a want to bail out as fast as possible).

Anyways, as long as wrappers are optional, I'm fine with it.

@psychon
Copy link
Owner Author

psychon commented Jun 5, 2021

Yeah, this is definitely not useful for everyone.

Why I did this: I recently implemented paste (ICCCM selection transfers) "just because". For the transfer, the code creates a window that is destroyed at the end. I ended up writing another version of WindowWrapper for this to make sure this temporary window is always destroyed: linebender/druid@48e5a21#diff-d692afae7592991d6306b5f4fde771c27317f806d752bcf713370b27356ce1f7R157

There is also code like this: https://github.com/linebender/druid/blob/f74a7120fa724b2d6dba88573942aa9864c16b94/druid-shell/src/platform/x11/window.rs#L290

The line in question is a create_window request. After this request, there are 10 ?. Most of them would lead to a "window leak" if they return. I feel like code like this would really benefit from "something RAII".

because drop can be called during a panic

Hm, yeah... So, what do you think? I described how I ended up writing this PR. Am I approaching this completely wrong or could this still be useful?

I am not sure how much that drop-during-panic is a problem. If it is, the code could check whether a panic is in progress and not free the window in this case, but this seems like a weird special case to me...

Anyways, as long as wrappers are optional, I'm fine with it.

Yeah, this definitely cannot become the only possible way. Self-referential structs and all. I guess I'd want to add something like this for "everything" (not only core-protocol). Writing this by hand is way too cumbersome and proc_macro also seems complicated, so I guess I'd want to eventually move this into generator/. Something like a hardcoded list inside the code generator or perhaps via extra XML: #589. But that shouldn't change the public API of these wrappers, so this PR is mostly about that (and whether adding this is a good idea at all).


Note to self: Before merging this, there should also be some into_window() method that consumes the WindowWrapper and returns the raw underlying window. That would be helpful for the code in druid, I think. I'll add that now.

This adds e.g. into_window() to WindowWrapper which consumes the wrapper
and returns the underlying XID without destroying the window.

Signed-off-by: Uli Schlachter <psychon@znc.in>
@mergify mergify bot merged commit 9fdbabf into master Jun 5, 2021
@mergify mergify bot deleted the resource-wrappers branch June 5, 2021 18:03
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants