Formalize thread-safety guarantees (#322)

This commit is contained in:
Victor Berger 2017-10-18 20:40:21 +02:00 committed by tomaka
parent 48902297b7
commit 229029f2da
5 changed files with 40 additions and 10 deletions

View file

@ -4,6 +4,8 @@
- Added method `MonitorId::get_hidpi_factor`.
- Deprecated `get_inner_size_pixels` and `get_inner_size_points` methods of `Window` in favor of
`get_inner_size`.
- **Breaking:** `EventsLoop` is `!Send` and `!Sync` because of platform-dependant constraints,
but `Window`, `WindowId`, `DeviceId` and `MonitorId` guaranteed to be `Send`.
# Version 0.8.3 (2017-10-11)

View file

@ -167,8 +167,14 @@ pub struct DeviceId(platform::DeviceId);
/// an events loop opens a connection to the X or Wayland server.
///
/// To wake up an `EventsLoop` from a another thread, see the `EventsLoopProxy` docs.
///
/// Note that the `EventsLoop` cannot be shared accross threads (due to platform-dependant logic
/// forbiding it), as such it is neither `Send` nor `Sync`. If you need cross-thread access, the
/// `Window` created from this `EventsLoop` _can_ be sent to an other thread, and the
/// `EventsLoopProxy` allows you to wakeup an `EventsLoop` from an other thread.
pub struct EventsLoop {
events_loop: platform::EventsLoop,
_marker: ::std::marker::PhantomData<*mut ()> // Not Send nor Sync
}
/// Returned by the user callback given to the `EventsLoop::run_forever` method.
@ -192,6 +198,7 @@ impl EventsLoop {
pub fn new() -> EventsLoop {
EventsLoop {
events_loop: platform::EventsLoop::new(),
_marker: ::std::marker::PhantomData,
}
}

View file

@ -41,7 +41,12 @@ pub trait EventsLoopExt {
impl EventsLoopExt for EventsLoop {
#[inline]
fn new_x11() -> Result<Self, XNotSupported> {
LinuxEventsLoop::new_x11().map(|ev| EventsLoop { events_loop: ev })
LinuxEventsLoop::new_x11().map(|ev|
EventsLoop {
events_loop: ev,
_marker: ::std::marker::PhantomData,
}
)
}
#[inline]
@ -50,7 +55,8 @@ impl EventsLoopExt for EventsLoop {
events_loop: match LinuxEventsLoop::new_wayland() {
Ok(e) => e,
Err(_) => panic!() // TODO: propagate
}
},
_marker: ::std::marker::PhantomData,
}
}

View file

@ -1,8 +0,0 @@
extern crate winit;
#[test]
fn events_loop_proxy_send() {
// ensures that `winit::EventsLoopProxy` implements `Send`
fn needs_send<T:Send>() {}
needs_send::<winit::EventsLoopProxy>();
}

23
tests/send_objects.rs Normal file
View file

@ -0,0 +1,23 @@
extern crate winit;
fn needs_send<T:Send>() {}
#[test]
fn events_loop_proxy_send() {
// ensures that `winit::EventsLoopProxy` implements `Send`
needs_send::<winit::EventsLoopProxy>();
}
#[test]
fn window_send() {
// ensures that `winit::Window` implements `Send`
needs_send::<winit::Window>();
}
#[test]
fn ids_send() {
// ensures that the various `..Id` types implement `Send`
needs_send::<winit::WindowId>();
needs_send::<winit::DeviceId>();
needs_send::<winit::MonitorId>();
}