Skip to content

Commit

Permalink
Use a wrapper type implementing Sync, instead of static mut
Browse files Browse the repository at this point in the history
`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.
  • Loading branch information
ids1024 committed Feb 12, 2024
1 parent eb7a57b commit 8aadd9a
Show file tree
Hide file tree
Showing 2 changed files with 445 additions and 416 deletions.
38 changes: 18 additions & 20 deletions wayland-scanner/src/c_interfaces.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
use std::cmp;
use std::iter::repeat;

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

let types_null_len = Literal::usize_unsuffixed(longest_nulls);

let nulls = repeat(quote! { NULLPTR as *const wayland_backend::protocol::wl_interface })
.take(longest_nulls);

quote! {
const NULLPTR: *const std::os::raw::c_void = 0 as *const std::os::raw::c_void;
static mut types_null: [*const wayland_backend::protocol::wl_interface; #types_null_len] = [
#(#nulls,)*
];
use std::ptr::null;
struct SyncWrapper<T>(T);
unsafe impl<T> Sync for SyncWrapper<T> {}
static types_null: SyncWrapper<[*const wayland_backend::protocol::wl_interface; #types_null_len]> = SyncWrapper([
null::<wayland_backend::protocol::wl_interface>(); #types_null_len
]);
}
}

Expand All @@ -47,24 +45,24 @@ pub(crate) fn generate_interface(interface: &Interface) -> TokenStream {
let version_value = Literal::i32_unsuffixed(interface.version as i32);
let request_count_value = Literal::i32_unsuffixed(interface.requests.len() as i32);
let requests_value = if interface.requests.is_empty() {
quote! { NULLPTR as *const wayland_backend::protocol::wl_message }
quote! { null::<wayland_backend::protocol::wl_message>() }
} else {
let requests_ident = format_ident!("{}_requests", interface.name);
quote! { unsafe { &#requests_ident as *const _ } }
quote! { #requests_ident.0.as_ptr() }
};
let event_count_value = Literal::i32_unsuffixed(interface.events.len() as i32);
let events_value = if interface.events.is_empty() {
quote! { NULLPTR as *const wayland_backend::protocol::wl_message }
quote! { null::<wayland_backend::protocol::wl_message>() }
} else {
let events_ident = format_ident!("{}_events", interface.name);
quote! { unsafe { &#events_ident as *const _ } }
quote! { #events_ident.0.as_ptr() }
};

quote! {
#requests
#events

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

Some(quote! {
static mut #array_ident: [*const wayland_backend::protocol::wl_interface; #array_len] = [
static #array_ident: SyncWrapper<[*const wayland_backend::protocol::wl_interface; #array_len]> = SyncWrapper([
#(#array_values,)*
];
]);
})
}
});
Expand All @@ -118,17 +116,17 @@ fn gen_messages(interface: &Interface, messages: &[Message], which: &str) -> Tok
wayland_backend::protocol::wl_message {
name: #name_value as *const u8 as *const std::os::raw::c_char,
signature: #signature_value as *const u8 as *const std::os::raw::c_char,
types: unsafe { &#types_ident as *const _ },
types: #types_ident.0.as_ptr(),
}
}
});

quote! {
#(#types_arrays)*

pub static mut #message_array_ident: [wayland_backend::protocol::wl_message; #message_array_len] = [
static #message_array_ident: SyncWrapper<[wayland_backend::protocol::wl_message; #message_array_len]> = SyncWrapper([
#(#message_array_values,)*
];
]);
}
}

Expand Down
Loading

0 comments on commit 8aadd9a

Please sign in to comment.