Allow platform references to be sent to background threads

Nathan Sobo and Max Brunsfeld created

Co-Authored-By: Max Brunsfeld <maxbrunsfeld@gmail.com>

Change summary

gpui/src/app.rs                   | 12 ++++++------
gpui/src/platform.rs              |  2 +-
gpui/src/platform/mac.rs          |  6 +++---
gpui/src/platform/mac/platform.rs |  3 +++
gpui/src/platform/test.rs         |  7 ++++---
5 files changed, 17 insertions(+), 13 deletions(-)

Detailed changes

gpui/src/app.rs 🔗

@@ -120,7 +120,7 @@ impl App {
         let foreground = Rc::new(executor::Foreground::test());
         let cx = Rc::new(RefCell::new(MutableAppContext::new(
             foreground,
-            Rc::new(platform),
+            Arc::new(platform),
             Rc::new(main_thread_platform),
             asset_source,
         )));
@@ -134,7 +134,7 @@ impl App {
         Fn: FnOnce(TestAppContext) -> F,
         F: Future<Output = T>,
     {
-        let platform = Rc::new(platform::test::platform());
+        let platform = Arc::new(platform::test::platform());
         let main_thread_platform = Rc::new(platform::test::main_thread_platform());
         let foreground = Rc::new(executor::Foreground::test());
         let cx = TestAppContext {
@@ -361,7 +361,7 @@ impl TestAppContext {
         self.cx.borrow().cx.font_cache.clone()
     }
 
-    pub fn platform(&self) -> Rc<dyn platform::Platform> {
+    pub fn platform(&self) -> Arc<dyn platform::Platform> {
         self.cx.borrow().platform.clone()
     }
 
@@ -530,7 +530,7 @@ type GlobalActionCallback = dyn FnMut(&dyn Any, &mut MutableAppContext);
 pub struct MutableAppContext {
     weak_self: Option<rc::Weak<RefCell<Self>>>,
     main_thread_platform: Rc<dyn platform::MainThreadPlatform>,
-    platform: Rc<dyn platform::Platform>,
+    platform: Arc<dyn platform::Platform>,
     assets: Arc<AssetCache>,
     cx: AppContext,
     actions: HashMap<TypeId, HashMap<String, Vec<Box<ActionCallback>>>>,
@@ -553,7 +553,7 @@ pub struct MutableAppContext {
 impl MutableAppContext {
     fn new(
         foreground: Rc<executor::Foreground>,
-        platform: Rc<dyn platform::Platform>,
+        platform: Arc<dyn platform::Platform>,
         main_thread_platform: Rc<dyn platform::MainThreadPlatform>,
         asset_source: impl AssetSource,
     ) -> Self {
@@ -594,7 +594,7 @@ impl MutableAppContext {
         App(self.weak_self.as_ref().unwrap().upgrade().unwrap())
     }
 
-    pub fn platform(&self) -> Rc<dyn platform::Platform> {
+    pub fn platform(&self) -> Arc<dyn platform::Platform> {
         self.platform.clone()
     }
 

gpui/src/platform.rs 🔗

@@ -48,7 +48,7 @@ pub(crate) trait MainThreadPlatform {
     );
 }
 
-pub trait Platform {
+pub trait Platform: Send + Sync {
     fn dispatcher(&self) -> Arc<dyn Dispatcher>;
     fn fonts(&self) -> Arc<dyn FontSystem>;
 

gpui/src/platform/mac.rs 🔗

@@ -12,15 +12,15 @@ use cocoa::base::{BOOL, NO, YES};
 pub use dispatcher::Dispatcher;
 pub use fonts::FontSystem;
 use platform::{MacMainThreadPlatform, MacPlatform};
-use std::rc::Rc;
+use std::{rc::Rc, sync::Arc};
 use window::Window;
 
 pub(crate) fn main_thread_platform() -> Rc<dyn super::MainThreadPlatform> {
     Rc::new(MacMainThreadPlatform::default())
 }
 
-pub(crate) fn platform() -> Rc<dyn super::Platform> {
-    Rc::new(MacPlatform::new())
+pub(crate) fn platform() -> Arc<dyn super::Platform> {
+    Arc::new(MacPlatform::new())
 }
 
 trait BoolExt {

gpui/src/platform/mac/platform.rs 🔗

@@ -329,6 +329,9 @@ impl MacPlatform {
     }
 }
 
+unsafe impl Send for MacPlatform {}
+unsafe impl Sync for MacPlatform {}
+
 impl platform::Platform for MacPlatform {
     fn dispatcher(&self) -> Arc<dyn platform::Dispatcher> {
         self.dispatcher.clone()

gpui/src/platform/test.rs 🔗

@@ -1,4 +1,5 @@
 use crate::ClipboardItem;
+use parking_lot::Mutex;
 use pathfinder_geometry::vector::Vector2F;
 use std::{
     any::Any,
@@ -11,7 +12,7 @@ use std::{
 pub(crate) struct Platform {
     dispatcher: Arc<dyn super::Dispatcher>,
     fonts: Arc<dyn super::FontSystem>,
-    current_clipboard_item: RefCell<Option<ClipboardItem>>,
+    current_clipboard_item: Mutex<Option<ClipboardItem>>,
 }
 
 #[derive(Default)]
@@ -114,11 +115,11 @@ impl super::Platform for Platform {
     fn quit(&self) {}
 
     fn write_to_clipboard(&self, item: ClipboardItem) {
-        *self.current_clipboard_item.borrow_mut() = Some(item);
+        *self.current_clipboard_item.lock() = Some(item);
     }
 
     fn read_from_clipboard(&self) -> Option<ClipboardItem> {
-        self.current_clipboard_item.borrow().clone()
+        self.current_clipboard_item.lock().clone()
     }
 }