Skip to content

Commit

Permalink
Add mutex for OSX.
Browse files Browse the repository at this point in the history
  • Loading branch information
MattX committed Jul 11, 2021
1 parent b7d2c3d commit 83cbe85
Show file tree
Hide file tree
Showing 3 changed files with 49 additions and 0 deletions.
1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ wayland = ["smithay-clipboard"]
clipboard-win = "3.0.2"

[target.'cfg(target_os = "macos")'.dependencies]
lazy_static = "1.4"
objc = "0.2"
objc_id = "0.1"
objc-foundation = "0.1"
Expand Down
19 changes: 19 additions & 0 deletions src/osx_clipboard.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,9 @@
// limitations under the License.

use std::mem::transmute;
use std::sync::Mutex;

use lazy_static::lazy_static;
use objc::runtime::{Class, Object};
use objc::{msg_send, sel, sel_impl};
use objc_foundation::{INSArray, INSObject, INSString};
Expand All @@ -22,6 +24,11 @@ use objc_id::{Id, Owned};

use crate::common::*;

// creating or accessing the context is not thread-safe, and needs to be protected
lazy_static! {
static ref CLIPBOARD_CONTEXT_MUTEX: Mutex<()> = Mutex::new(());
}

pub struct OSXClipboardContext {
pasteboard: Id<Object>,
}
Expand All @@ -32,6 +39,10 @@ extern "C" {}

impl OSXClipboardContext {
pub fn new() -> Result<OSXClipboardContext> {
let lock = CLIPBOARD_CONTEXT_MUTEX.lock();
if !lock.is_ok() {
return Err("could not acquire mutex".into());
}
let cls = Class::get("NSPasteboard").ok_or("Class::get(\"NSPasteboard\")")?;
let pasteboard: *mut Object = unsafe { msg_send![cls, generalPasteboard] };
if pasteboard.is_null() {
Expand All @@ -44,6 +55,10 @@ impl OSXClipboardContext {

impl ClipboardProvider for OSXClipboardContext {
fn get_contents(&mut self) -> Result<String> {
let lock = CLIPBOARD_CONTEXT_MUTEX.lock();
if !lock.is_ok() {
return Err("could not acquire mutex".into());
}
let string_class: Id<NSObject> = {
let cls: Id<Class> = unsafe { Id::from_ptr(class("NSString")) };
unsafe { transmute(cls) }
Expand All @@ -66,6 +81,10 @@ impl ClipboardProvider for OSXClipboardContext {
}

fn set_contents(&mut self, data: String) -> Result<()> {
let lock = CLIPBOARD_CONTEXT_MUTEX.lock();
if !lock.is_ok() {
return Err("could not acquire mutex".into());
}
let string_array = NSArray::from_vec(vec![NSString::from_str(&data)]);
let _: usize = unsafe { msg_send![self.pasteboard, clearContents] };
let success: bool = unsafe { msg_send![self.pasteboard, writeObjects: string_array] };
Expand Down
29 changes: 29 additions & 0 deletions tests/concurrency.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
use copypasta::{ClipboardContext, ClipboardProvider};

fn some_other_fn() {
let mut ctx = ClipboardContext::new().unwrap();
ctx.get_contents().unwrap();
}

#[cfg(test)]
mod tests {
use super::*;

#[test]
fn foo() {
let mut ctx = ClipboardContext::new().unwrap();
ctx.set_contents("Dummy".into()).unwrap();
ctx.get_contents().unwrap();

some_other_fn();
}

#[test]
fn bar() {
let mut ctx = ClipboardContext::new().unwrap();
ctx.set_contents("Dummy".into()).unwrap();
ctx.get_contents().unwrap();

some_other_fn();
}
}

0 comments on commit 83cbe85

Please sign in to comment.