diff options
| author | a-kenji <aks.kenji@protonmail.com> | 2021-05-16 12:44:56 +0200 |
|---|---|---|
| committer | a-kenji <aks.kenji@protonmail.com> | 2021-05-16 12:44:56 +0200 |
| commit | 197f31875646a5b78abd23edecee072931b2b14b (patch) | |
| tree | a8fb17d057d77c0a5090c5e1878ecd5618ec592d /src/common | |
| parent | Split Layout Flag (diff) | |
| parent | Docs(changelog): Multiprocess model #499 (diff) | |
| download | sl0ppij-197f31875646a5b78abd23edecee072931b2b14b.tar.gz sl0ppij-197f31875646a5b78abd23edecee072931b2b14b.tar.xz sl0ppij-197f31875646a5b78abd23edecee072931b2b14b.zip | |
Merge branch 'main' of https://github.com/zellij-org/zellij into layout-path-506
Diffstat (limited to 'src/common')
| -rw-r--r-- | src/common/errors.rs | 40 | ||||
| -rw-r--r-- | src/common/input/handler.rs | 8 | ||||
| -rw-r--r-- | src/common/ipc.rs | 32 | ||||
| -rw-r--r-- | src/common/os_input_output.rs | 67 | ||||
| -rw-r--r-- | src/common/pty.rs | 4 | ||||
| -rw-r--r-- | src/common/screen.rs | 4 | ||||
| -rw-r--r-- | src/common/utils/consts.rs | 4 | ||||
| -rw-r--r-- | src/common/wasm_vm.rs | 4 |
8 files changed, 100 insertions, 63 deletions
diff --git a/src/common/errors.rs b/src/common/errors.rs index c2caf19d..262dfd6b 100644 --- a/src/common/errors.rs +++ b/src/common/errors.rs @@ -19,12 +19,29 @@ const MAX_THREAD_CALL_STACK: usize = 6; use super::thread_bus::SenderWithContext; #[cfg(not(test))] use std::panic::PanicInfo; + +pub trait ErrorInstruction { + fn error(err: String) -> Self; +} + +impl ErrorInstruction for ClientInstruction { + fn error(err: String) -> Self { + ClientInstruction::Error(err) + } +} + +impl ErrorInstruction for ServerInstruction { + fn error(err: String) -> Self { + ServerInstruction::Error(err) + } +} + /// Custom panic handler/hook. Prints the [`ErrorContext`]. #[cfg(not(test))] -pub fn handle_panic( - info: &PanicInfo<'_>, - send_app_instructions: &SenderWithContext<ClientInstruction>, -) { +pub fn handle_panic<T>(info: &PanicInfo<'_>, sender: &SenderWithContext<T>) +where + T: ErrorInstruction + Clone, +{ use backtrace::Backtrace; use std::{process, thread}; let backtrace = Backtrace::new(); @@ -70,7 +87,7 @@ pub fn handle_panic( println!("{}", backtrace); process::exit(1); } else { - let _ = send_app_instructions.send(ClientInstruction::Error(backtrace)); + let _ = sender.send(T::error(backtrace)); } } @@ -103,6 +120,11 @@ impl ErrorContext { break; } } + self.update_thread_ctx() + } + + /// Updates the thread local [`ErrorContext`]. + pub fn update_thread_ctx(&self) { ASYNCOPENCALLS .try_with(|ctx| *ctx.borrow_mut() = *self) .unwrap_or_else(|_| OPENCALLS.with(|ctx| *ctx.borrow_mut() = *self)); @@ -333,6 +355,7 @@ pub enum ClientContext { Error, UnblockInputThread, Render, + ServerError, } impl From<&ClientInstruction> for ClientContext { @@ -340,6 +363,7 @@ impl From<&ClientInstruction> for ClientContext { match *client_instruction { ClientInstruction::Exit => ClientContext::Exit, ClientInstruction::Error(_) => ClientContext::Error, + ClientInstruction::ServerError(_) => ClientContext::ServerError, ClientInstruction::Render(_) => ClientContext::Render, ClientInstruction::UnblockInputThread => ClientContext::UnblockInputThread, } @@ -350,22 +374,20 @@ impl From<&ClientInstruction> for ClientContext { #[derive(Debug, Clone, Copy, PartialEq, Serialize, Deserialize)] pub enum ServerContext { NewClient, - Action, Render, - TerminalResize, UnblockInputThread, ClientExit, + Error, } impl From<&ServerInstruction> for ServerContext { fn from(server_instruction: &ServerInstruction) -> Self { match *server_instruction { ServerInstruction::NewClient(..) => ServerContext::NewClient, - ServerInstruction::Action(_) => ServerContext::Action, - ServerInstruction::TerminalResize(_) => ServerContext::TerminalResize, ServerInstruction::Render(_) => ServerContext::Render, ServerInstruction::UnblockInputThread => ServerContext::UnblockInputThread, ServerInstruction::ClientExit => ServerContext::ClientExit, + ServerInstruction::Error(_) => ServerContext::Error, } } } diff --git a/src/common/input/handler.rs b/src/common/input/handler.rs index b2f4d0a3..4ac2cf83 100644 --- a/src/common/input/handler.rs +++ b/src/common/input/handler.rs @@ -4,10 +4,10 @@ use super::actions::Action; use super::keybinds::Keybinds; use crate::client::ClientInstruction; use crate::common::input::config::Config; +use crate::common::ipc::ClientToServerMsg; use crate::common::thread_bus::{SenderWithContext, OPENCALLS}; use crate::errors::ContextType; use crate::os_input_output::ClientOsApi; -use crate::server::ServerInstruction; use crate::CommandIsExecuting; use termion::input::{TermRead, TermReadEventsAndRaw}; @@ -139,7 +139,7 @@ impl InputHandler { Action::SwitchToMode(mode) => { self.mode = mode; self.os_input - .send_to_server(ServerInstruction::Action(action)); + .send_to_server(ClientToServerMsg::Action(action)); } Action::CloseFocus | Action::NewPane(_) @@ -151,13 +151,13 @@ impl InputHandler { | Action::MoveFocusOrTab(_) => { self.command_is_executing.blocking_input_thread(); self.os_input - .send_to_server(ServerInstruction::Action(action)); + .send_to_server(ClientToServerMsg::Action(action)); self.command_is_executing .wait_until_input_thread_is_unblocked(); } _ => self .os_input - .send_to_server(ServerInstruction::Action(action)), + .send_to_server(ClientToServerMsg::Action(action)), } should_break diff --git a/src/common/ipc.rs b/src/common/ipc.rs index 190680dc..129727a1 100644 --- a/src/common/ipc.rs +++ b/src/common/ipc.rs @@ -1,10 +1,14 @@ //! IPC stuff for starting to split things into a client and server model. -use crate::common::errors::{get_current_ctx, ErrorContext}; +use crate::cli::CliArgs; +use crate::common::{ + errors::{get_current_ctx, ErrorContext}, + input::{actions::Action, options::Options}, +}; +use crate::panes::PositionAndSize; use interprocess::local_socket::LocalSocketStream; use nix::unistd::dup; use serde::{Deserialize, Serialize}; -use std::collections::HashSet; use std::io::{self, Write}; use std::marker::PhantomData; use std::os::unix::io::{AsRawFd, FromRawFd}; @@ -29,9 +33,9 @@ pub enum ClientType { } // Types of messages sent from the client to the server -#[derive(Serialize, Deserialize)] -pub enum _ClientToServerMsg { - // List which sessions are available +#[derive(Serialize, Deserialize, Debug, Clone)] +pub enum ClientToServerMsg { + /*// List which sessions are available ListSessions, // Create a new session CreateSession, @@ -40,16 +44,24 @@ pub enum _ClientToServerMsg { // Force detach DetachSession(SessionId), // Disconnect from the session we're connected to - DisconnectFromSession, + DisconnectFromSession,*/ + ClientExit, + TerminalResize(PositionAndSize), + NewClient(PositionAndSize, CliArgs, Options), + Action(Action), } // Types of messages sent from the server to the client -// @@@ Implement Serialize and Deserialize for this... -pub enum _ServerToClientMsg { - // Info about a particular session +#[derive(Serialize, Deserialize, Debug, Clone)] +pub enum ServerToClientMsg { + /*// Info about a particular session SessionInfo(Session), // A list of sessions - SessionList(HashSet<Session>), + SessionList(HashSet<Session>),*/ + Render(Option<String>), + UnblockInputThread, + Exit, + ServerError(String), } /// Sends messages on a stream socket, along with an [`ErrorContext`]. diff --git a/src/common/os_input_output.rs b/src/common/os_input_output.rs index 6f891e0d..adde6fdf 100644 --- a/src/common/os_input_output.rs +++ b/src/common/os_input_output.rs @@ -1,11 +1,8 @@ -use crate::client::ClientInstruction; -use crate::common::{ - ipc::{IpcReceiverWithContext, IpcSenderWithContext}, - utils::consts::ZELLIJ_IPC_PIPE, +use crate::common::ipc::{ + ClientToServerMsg, IpcReceiverWithContext, IpcSenderWithContext, ServerToClientMsg, }; use crate::errors::ErrorContext; use crate::panes::PositionAndSize; -use crate::server::ServerInstruction; use crate::utils::shared::default_palette; use interprocess::local_socket::LocalSocketStream; use nix::fcntl::{fcntl, FcntlArg, OFlag}; @@ -170,8 +167,8 @@ fn spawn_terminal(file_to_open: Option<PathBuf>, orig_termios: termios::Termios) #[derive(Clone)] pub struct ServerOsInputOutput { orig_termios: Arc<Mutex<termios::Termios>>, - receive_instructions_from_client: Option<Arc<Mutex<IpcReceiverWithContext<ServerInstruction>>>>, - send_instructions_to_client: Arc<Mutex<Option<IpcSenderWithContext<ClientInstruction>>>>, + receive_instructions_from_client: Option<Arc<Mutex<IpcReceiverWithContext<ClientToServerMsg>>>>, + send_instructions_to_client: Arc<Mutex<Option<IpcSenderWithContext<ServerToClientMsg>>>>, } /// The `ServerOsApi` trait represents an abstract interface to the features of an operating system that @@ -195,9 +192,9 @@ pub trait ServerOsApi: Send + Sync { /// Returns a [`Box`] pointer to this [`ServerOsApi`] struct. fn box_clone(&self) -> Box<dyn ServerOsApi>; /// Receives a message on server-side IPC channel - fn recv_from_client(&self) -> (ServerInstruction, ErrorContext); + fn recv_from_client(&self) -> (ClientToServerMsg, ErrorContext); /// Sends a message to client - fn send_to_client(&self, msg: ClientInstruction); + fn send_to_client(&self, msg: ServerToClientMsg); /// Adds a sender to client fn add_client_sender(&mut self); /// Update the receiver socket for the client @@ -236,7 +233,7 @@ impl ServerOsApi for ServerOsInputOutput { waitpid(Pid::from_raw(pid), None).unwrap(); Ok(()) } - fn recv_from_client(&self) -> (ServerInstruction, ErrorContext) { + fn recv_from_client(&self) -> (ClientToServerMsg, ErrorContext) { self.receive_instructions_from_client .as_ref() .unwrap() @@ -244,7 +241,7 @@ impl ServerOsApi for ServerOsInputOutput { .unwrap() .recv() } - fn send_to_client(&self, msg: ClientInstruction) { + fn send_to_client(&self, msg: ServerToClientMsg) { self.send_instructions_to_client .lock() .unwrap() @@ -291,8 +288,8 @@ pub fn get_server_os_input() -> ServerOsInputOutput { #[derive(Clone)] pub struct ClientOsInputOutput { orig_termios: Arc<Mutex<termios::Termios>>, - send_instructions_to_server: Arc<Mutex<Option<IpcSenderWithContext<ServerInstruction>>>>, - receive_instructions_from_server: Arc<Mutex<Option<IpcReceiverWithContext<ClientInstruction>>>>, + send_instructions_to_server: Arc<Mutex<Option<IpcSenderWithContext<ClientToServerMsg>>>>, + receive_instructions_from_server: Arc<Mutex<Option<IpcReceiverWithContext<ServerToClientMsg>>>>, } /// The `ClientOsApi` trait represents an abstract interface to the features of an operating system that @@ -305,7 +302,7 @@ pub trait ClientOsApi: Send + Sync { fn set_raw_mode(&mut self, fd: RawFd); /// Set the terminal associated to file descriptor `fd` to /// [cooked mode](https://en.wikipedia.org/wiki/Terminal_mode). - fn unset_raw_mode(&mut self, fd: RawFd); + fn unset_raw_mode(&self, fd: RawFd); /// Returns the writer that allows writing to standard output. fn get_stdout_writer(&self) -> Box<dyn io::Write>; /// Returns the raw contents of standard input. @@ -313,13 +310,13 @@ pub trait ClientOsApi: Send + Sync { /// Returns a [`Box`] pointer to this [`ClientOsApi`] struct. fn box_clone(&self) -> Box<dyn ClientOsApi>; /// Sends a message to the server. - fn send_to_server(&self, msg: ServerInstruction); + fn send_to_server(&self, msg: ClientToServerMsg); /// Receives a message on client-side IPC channel // This should be called from the client-side router thread only. - fn recv_from_server(&self) -> (ClientInstruction, ErrorContext); - fn receive_sigwinch(&self, cb: Box<dyn Fn()>); + fn recv_from_server(&self) -> (ServerToClientMsg, ErrorContext); + fn handle_signals(&self, sigwinch_cb: Box<dyn Fn()>, quit_cb: Box<dyn Fn()>); /// Establish a connection with the server socket. - fn connect_to_server(&self); + fn connect_to_server(&self, path: &Path); } impl ClientOsApi for ClientOsInputOutput { @@ -329,7 +326,7 @@ impl ClientOsApi for ClientOsInputOutput { fn set_raw_mode(&mut self, fd: RawFd) { into_raw_mode(fd); } - fn unset_raw_mode(&mut self, fd: RawFd) { + fn unset_raw_mode(&self, fd: RawFd) { let orig_termios = self.orig_termios.lock().unwrap(); unset_raw_mode(fd, orig_termios.clone()); } @@ -349,7 +346,7 @@ impl ClientOsApi for ClientOsInputOutput { let stdout = ::std::io::stdout(); Box::new(stdout) } - fn send_to_server(&self, msg: ServerInstruction) { + fn send_to_server(&self, msg: ClientToServerMsg) { self.send_instructions_to_server .lock() .unwrap() @@ -357,7 +354,7 @@ impl ClientOsApi for ClientOsInputOutput { .unwrap() .send(msg); } - fn recv_from_server(&self) -> (ClientInstruction, ErrorContext) { + fn recv_from_server(&self) -> (ServerToClientMsg, ErrorContext) { self.receive_instructions_from_server .lock() .unwrap() @@ -365,28 +362,34 @@ impl ClientOsApi for ClientOsInputOutput { .unwrap() .recv() } - fn receive_sigwinch(&self, cb: Box<dyn Fn()>) { - let mut signals = Signals::new(&[SIGWINCH, SIGTERM, SIGINT, SIGQUIT]).unwrap(); + fn handle_signals(&self, sigwinch_cb: Box<dyn Fn()>, quit_cb: Box<dyn Fn()>) { + let mut signals = Signals::new(&[SIGWINCH, SIGTERM, SIGINT, SIGQUIT, SIGHUP]).unwrap(); for signal in signals.forever() { match signal { SIGWINCH => { - cb(); + sigwinch_cb(); } - SIGTERM | SIGINT | SIGQUIT => { + SIGTERM | SIGINT | SIGQUIT | SIGHUP => { + quit_cb(); break; } _ => unreachable!(), } } } - fn connect_to_server(&self) { - let socket = match LocalSocketStream::connect(&**ZELLIJ_IPC_PIPE) { - Ok(sock) => sock, - Err(_) => { - std::thread::sleep(std::time::Duration::from_millis(20)); - LocalSocketStream::connect(&**ZELLIJ_IPC_PIPE).unwrap() + fn connect_to_server(&self, path: &Path) { + let socket; + loop { + match LocalSocketStream::connect(path) { + Ok(sock) => { + socket = sock; + break; + } + Err(_) => { + std::thread::sleep(std::time::Duration::from_millis(50)); + } } - }; + } let sender = IpcSenderWithContext::new(socket); let receiver = sender.get_receiver(); *self.send_instructions_to_server.lock().unwrap() = Some(sender); diff --git a/src/common/pty.rs b/src/common/pty.rs index 3c471d6a..5f5442b5 100644 --- a/src/common/pty.rs +++ b/src/common/pty.rs @@ -8,7 +8,7 @@ use std::pin::*; use std::time::{Duration, Instant}; use crate::client::panes::PaneId; -use crate::common::errors::{get_current_ctx, ContextType, PtyContext}; +use crate::common::errors::{get_current_ctx, ContextType}; use crate::common::screen::ScreenInstruction; use crate::common::thread_bus::{Bus, ThreadSenders}; use crate::layout::Layout; @@ -87,7 +87,7 @@ pub struct Pty { pub fn pty_thread_main(mut pty: Pty, maybe_layout: Option<Layout>) { loop { let (event, mut err_ctx) = pty.bus.recv().expect("failed to receive event on channel"); - err_ctx.add_call(ContextType::Pty(PtyContext::from(&event))); + err_ctx.add_call(ContextType::Pty((&event).into())); match event { PtyInstruction::SpawnTerminal(file_to_open) => { let pid = pty.spawn_terminal(file_to_open); diff --git a/src/common/screen.rs b/src/common/screen.rs index bc99f953..62fcec19 100644 --- a/src/common/screen.rs +++ b/src/common/screen.rs @@ -7,7 +7,7 @@ use std::str; use crate::common::input::options::Options; use crate::common::pty::{PtyInstruction, VteBytes}; use crate::common::thread_bus::Bus; -use crate::errors::{ContextType, ScreenContext}; +use crate::errors::ContextType; use crate::layout::Layout; use crate::panes::PaneId; use crate::panes::PositionAndSize; @@ -353,7 +353,7 @@ pub fn screen_thread_main( .bus .recv() .expect("failed to receive event on channel"); - err_ctx.add_call(ContextType::Screen(ScreenContext::from(&event))); + err_ctx.add_call(ContextType::Screen((&event).into())); match event { ScreenInstruction::PtyBytes(pid, vte_bytes) => { let active_tab = screen.get_active_tab_mut().unwrap(); diff --git a/src/common/utils/consts.rs b/src/common/utils/consts.rs index 479405c3..42843eb8 100644 --- a/src/common/utils/consts.rs +++ b/src/common/utils/consts.rs @@ -49,6 +49,6 @@ lazy_static! { } pub const FEATURES: &[&str] = &[ - #[cfg(feature = "enable_automatic_asset_installation")] - "enable_automatic_asset_installation", + #[cfg(feature = "disable_automatic_asset_installation")] + "disable_automatic_asset_installation", ]; diff --git a/src/common/wasm_vm.rs b/src/common/wasm_vm.rs index e5567285..51eb4ed8 100644 --- a/src/common/wasm_vm.rs +++ b/src/common/wasm_vm.rs @@ -15,7 +15,7 @@ use wasmer::{ use wasmer_wasi::{Pipe, WasiEnv, WasiState}; use zellij_tile::data::{Event, EventType, PluginIds}; -use crate::common::errors::{ContextType, PluginContext}; +use crate::common::errors::ContextType; use crate::common::pty::PtyInstruction; use crate::common::screen::ScreenInstruction; use crate::common::thread_bus::{Bus, ThreadSenders}; @@ -44,7 +44,7 @@ pub fn wasm_thread_main(bus: Bus<PluginInstruction>, store: Store, data_dir: Pat let mut plugin_map = HashMap::new(); loop { let (event, mut err_ctx) = bus.recv().expect("failed to receive event on channel"); - err_ctx.add_call(ContextType::Plugin(PluginContext::from(&event))); + err_ctx.add_call(ContextType::Plugin((&event).into())); match event { PluginInstruction::Load(pid_tx, path) => { let plugin_dir = data_dir.join("plugins/"); |
