Skip to content

Commit ea03873

Browse files
authored
Use a wrapper type implementing Sync, instead of static mut (#700)
* Use a wrapper type implementing `Sync`, instead of `static mut` `static mut` is generally best avoided. It seems to only be necessary currently to allow the use of non-`Sync` types, since pointers are not sync. This also removes the `NULLPTR` constant in favor of using `std::ptr::null`, uses `.as_ptr()` instead of casting, and uses the arrray repeating syntax to define `types_null`. None of those should impact behavior or the public API. `*_requests` and `*_events` static are no longer public now. This is theoretically a breaking change, but shouldn't really impact anything. * Suppress `clippy::test_attr_in_doctest` lint * Address nightly warnings
1 parent eb7a57b commit ea03873

File tree

9 files changed

+452
-422
lines changed

9 files changed

+452
-422
lines changed

wayland-backend/src/rs/client_impl/mod.rs

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,6 @@ use super::{
2828
wire::MessageParseError,
2929
};
3030

31-
pub use crate::types::client::{InvalidId, NoWaylandLib, WaylandError};
32-
3331
#[derive(Debug, Clone)]
3432
struct Data {
3533
client_destroyed: bool,
@@ -407,7 +405,7 @@ impl InnerBackend {
407405
// Prepare the message in a debug-compatible way
408406
let args = args.into_iter().map(|arg| {
409407
if let Argument::NewId(ObjectId { id: p }) = arg {
410-
if !p.id == 0 {
408+
if p.id != 0 {
411409
panic!("The newid provided when sending request {}@{}.{} is not a placeholder.", object.interface.name, id.id, message_desc.name);
412410
}
413411
if let Some((child_id, child_serial, child_interface)) = child {

wayland-backend/src/rs/wire.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
//! Types and routines used to manipulate arguments from the wire format
22
33
use std::collections::VecDeque;
4-
use std::convert::TryInto;
54
use std::ffi::CStr;
65
use std::os::unix::io::RawFd;
76
use std::os::unix::io::{BorrowedFd, OwnedFd};

wayland-backend/src/sys/client_impl/mod.rs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,6 @@ use smallvec::SmallVec;
2929

3030
use wayland_sys::{client::*, common::*, ffi_dispatch};
3131

32-
pub use crate::types::client::{InvalidId, NoWaylandLib, WaylandError};
33-
3432
use super::{free_arrays, RUST_MANAGED};
3533

3634
use super::client::*;

wayland-backend/src/sys/server_impl/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ use wayland_sys::{common::*, ffi_dispatch, server::*};
2525

2626
use super::{free_arrays, server::*, RUST_MANAGED};
2727

28+
#[allow(unused_imports)]
2829
pub use crate::types::server::{Credentials, DisconnectReason, GlobalInfo, InitError, InvalidId};
2930

3031
scoped_thread_local! {

wayland-backend/tests/rs_sys_impls.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
#![allow(clippy::test_attr_in_doctest)]
2+
13
//! Tests to ensure the rust and sys types implement the same traits.
24
35
/// A macro used to assert a type defined in both the rust and sys implementations of wayland-backend

wayland-scanner/CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22

33
## Unreleased
44

5+
- Use wrapper type implementing `Sync` instead of `static mut`s.
6+
57
## 0.31.1 -- 2024-01-29
68

79
- Include an `std::convert::Infallible` in hidden `__phantom_lifetime` enum variants,

wayland-scanner/src/c_interfaces.rs

Lines changed: 18 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
use std::cmp;
2-
use std::iter::repeat;
32

43
use proc_macro2::{Literal, TokenStream};
54
use quote::{format_ident, quote};
@@ -27,14 +26,13 @@ pub(crate) fn generate_interfaces_prefix(protocol: &Protocol) -> TokenStream {
2726

2827
let types_null_len = Literal::usize_unsuffixed(longest_nulls);
2928

30-
let nulls = repeat(quote! { NULLPTR as *const wayland_backend::protocol::wl_interface })
31-
.take(longest_nulls);
32-
3329
quote! {
34-
const NULLPTR: *const std::os::raw::c_void = 0 as *const std::os::raw::c_void;
35-
static mut types_null: [*const wayland_backend::protocol::wl_interface; #types_null_len] = [
36-
#(#nulls,)*
37-
];
30+
use std::ptr::null;
31+
struct SyncWrapper<T>(T);
32+
unsafe impl<T> Sync for SyncWrapper<T> {}
33+
static types_null: SyncWrapper<[*const wayland_backend::protocol::wl_interface; #types_null_len]> = SyncWrapper([
34+
null::<wayland_backend::protocol::wl_interface>(); #types_null_len
35+
]);
3836
}
3937
}
4038

@@ -47,24 +45,24 @@ pub(crate) fn generate_interface(interface: &Interface) -> TokenStream {
4745
let version_value = Literal::i32_unsuffixed(interface.version as i32);
4846
let request_count_value = Literal::i32_unsuffixed(interface.requests.len() as i32);
4947
let requests_value = if interface.requests.is_empty() {
50-
quote! { NULLPTR as *const wayland_backend::protocol::wl_message }
48+
quote! { null::<wayland_backend::protocol::wl_message>() }
5149
} else {
5250
let requests_ident = format_ident!("{}_requests", interface.name);
53-
quote! { unsafe { &#requests_ident as *const _ } }
51+
quote! { #requests_ident.0.as_ptr() }
5452
};
5553
let event_count_value = Literal::i32_unsuffixed(interface.events.len() as i32);
5654
let events_value = if interface.events.is_empty() {
57-
quote! { NULLPTR as *const wayland_backend::protocol::wl_message }
55+
quote! { null::<wayland_backend::protocol::wl_message>() }
5856
} else {
5957
let events_ident = format_ident!("{}_events", interface.name);
60-
quote! { unsafe { &#events_ident as *const _ } }
58+
quote! { #events_ident.0.as_ptr() }
6159
};
6260

6361
quote! {
6462
#requests
6563
#events
6664

67-
pub static mut #interface_ident: wayland_backend::protocol::wl_interface = wayland_backend::protocol::wl_interface {
65+
pub static #interface_ident: wayland_backend::protocol::wl_interface = wayland_backend::protocol::wl_interface {
6866
name: #name_value as *const u8 as *const std::os::raw::c_char,
6967
version: #version_value,
7068
request_count: #request_count_value,
@@ -89,15 +87,15 @@ fn gen_messages(interface: &Interface, messages: &[Message], which: &str) -> Tok
8987
let array_values = msg.args.iter().map(|arg| match (arg.typ, &arg.interface) {
9088
(Type::Object, &Some(ref inter)) | (Type::NewId, &Some(ref inter)) => {
9189
let interface_ident =format_ident!("{}_interface", inter);
92-
quote! { unsafe { &#interface_ident as *const wayland_backend::protocol::wl_interface } }
90+
quote! { &#interface_ident as *const wayland_backend::protocol::wl_interface }
9391
}
94-
_ => quote! { NULLPTR as *const wayland_backend::protocol::wl_interface },
92+
_ => quote! { null::<wayland_backend::protocol::wl_interface>() },
9593
});
9694

9795
Some(quote! {
98-
static mut #array_ident: [*const wayland_backend::protocol::wl_interface; #array_len] = [
96+
static #array_ident: SyncWrapper<[*const wayland_backend::protocol::wl_interface; #array_len]> = SyncWrapper([
9997
#(#array_values,)*
100-
];
98+
]);
10199
})
102100
}
103101
});
@@ -118,17 +116,17 @@ fn gen_messages(interface: &Interface, messages: &[Message], which: &str) -> Tok
118116
wayland_backend::protocol::wl_message {
119117
name: #name_value as *const u8 as *const std::os::raw::c_char,
120118
signature: #signature_value as *const u8 as *const std::os::raw::c_char,
121-
types: unsafe { &#types_ident as *const _ },
119+
types: #types_ident.0.as_ptr(),
122120
}
123121
}
124122
});
125123

126124
quote! {
127125
#(#types_arrays)*
128126

129-
pub static mut #message_array_ident: [wayland_backend::protocol::wl_message; #message_array_len] = [
127+
static #message_array_ident: SyncWrapper<[wayland_backend::protocol::wl_message; #message_array_len]> = SyncWrapper([
130128
#(#message_array_values,)*
131-
];
129+
]);
132130
}
133131
}
134132

0 commit comments

Comments
 (0)