Implement mutex for ui thread idle function

This commit is contained in:
daa84 2016-03-25 17:36:51 +03:00
parent e15727ff74
commit 193b4d573c
3 changed files with 45 additions and 39 deletions

View File

@ -3,6 +3,7 @@ extern crate cairo;
extern crate neovim_lib;
extern crate rmp;
mod ui_mutex;
mod nvim;
mod ui_model;
mod ui;

View File

@ -1,46 +1,8 @@
use neovim_lib::{Neovim, NeovimApi, Session};
use std::io::{Result, Error, ErrorKind};
use std::cell::UnsafeCell;
use std::thread;
use std::sync::Arc;
use rmp::Value;
use ui::Ui;
use gtk;
pub struct MainLoopMutex<T: Sized> {
data: UnsafeCell<T>,
main_thread_name: Option<String>,
}
unsafe impl<T: Sized + Send> Sync for MainLoopMutex<T> {}
impl<T> MainLoopMutex<T> {
pub fn new(t: T) -> MainLoopMutex<T> {
MainLoopMutex {
data: UnsafeCell::new(t),
main_thread_name: thread::current().name().map(|v| v.to_owned()),
}
}
// TODO: return some sort of ref guard here
pub fn get(&self) -> &mut T {
if thread::current().name().map(|v| v.to_owned()) != self.main_thread_name {
panic!("Can access value only from main thread");
}
unsafe { &mut *self.data.get() }
}
pub fn safe_call<F, I>(mutex: Arc<MainLoopMutex<I>>, cb: F)
where I: 'static,
F: Fn(&MainLoopMutex<I>) + 'static
{
gtk::idle_add(move || {
cb(&*mutex);
gtk::Continue(false)
});
}
}
pub struct Nvim {
nvim: Neovim,
@ -52,7 +14,7 @@ pub trait RedrawEvents {
impl Nvim {
pub fn start(mut ui: Ui) -> Result<Nvim> {
// let mut session = try!(Session::new_tcp("127.0.0.1:6666"));
let mut session = if cfg!(target_os = "windows") {
let session = if cfg!(target_os = "windows") {
Session::new_child_path("E:\\Neovim\\bin\\nvim.exe").unwrap()
} else {
Session::new_child().unwrap()

43
src/ui_mutex.rs Normal file
View File

@ -0,0 +1,43 @@
use std::cell::{RefCell, RefMut};
use std::thread;
use std::sync::Arc;
use gtk;
pub struct MainLoopMutex<T: Sized> {
data: RefCell<T>,
main_thread_name: Option<String>,
}
// here sync used to mark that internal data is acessed only from main thread
// this behaviour works because of borrow_mut check thread name
unsafe impl<T: Sized + Send> Sync for MainLoopMutex<T> {}
impl<T> MainLoopMutex<T> {
pub fn new(t: T) -> MainLoopMutex<T> {
MainLoopMutex {
data: RefCell::new(t),
main_thread_name: thread::current().name().map(|v| v.to_owned()),
}
}
pub fn borrow_mut(&self) -> RefMut<T> {
if thread::current().name().map(|v| v.to_owned()) != self.main_thread_name {
panic!("Can access value only from main thread");
}
self.data.borrow_mut()
}
pub fn safe_call<F, I>(mutex: Arc<MainLoopMutex<I>>, cb: F)
where I: 'static,
F: Fn(&MainLoopMutex<I>) + 'static
{
gtk::idle_add(move || {
cb(&*mutex);
gtk::Continue(false)
});
}
}