Implement mutex for ui thread idle function
This commit is contained in:
parent
e15727ff74
commit
193b4d573c
@ -3,6 +3,7 @@ extern crate cairo;
|
||||
extern crate neovim_lib;
|
||||
extern crate rmp;
|
||||
|
||||
mod ui_mutex;
|
||||
mod nvim;
|
||||
mod ui_model;
|
||||
mod ui;
|
||||
|
40
src/nvim.rs
40
src/nvim.rs
@ -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
43
src/ui_mutex.rs
Normal 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)
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user