aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKunal Mohan <kunalmohan99@gmail.com>2021-02-18 13:29:11 +0530
committerKunal Mohan <kunalmohan99@gmail.com>2021-05-04 20:47:49 +0530
commit5ece7f44ccfcbecbbc7dd2ce1ae3fb377e84ccbc (patch)
tree30a20a9cc77decbb1f901a67ef6ca836fc87dbff
parentensure proper shutdown (diff)
downloadsl0ppij-5ece7f44ccfcbecbbc7dd2ce1ae3fb377e84ccbc.tar.gz
sl0ppij-5ece7f44ccfcbecbbc7dd2ce1ae3fb377e84ccbc.tar.xz
sl0ppij-5ece7f44ccfcbecbbc7dd2ce1ae3fb377e84ccbc.zip
Use IPC for Server to client as well
Add router thread
-rw-r--r--src/common/errors.rs12
-rw-r--r--src/common/mod.rs100
-rw-r--r--src/common/pty_bus.rs2
-rw-r--r--src/common/screen.rs2
-rw-r--r--src/common/wasm_vm.rs2
-rw-r--r--src/server/mod.rs54
6 files changed, 98 insertions, 74 deletions
diff --git a/src/common/errors.rs b/src/common/errors.rs
index a9156ae6..1cdff574 100644
--- a/src/common/errors.rs
+++ b/src/common/errors.rs
@@ -194,7 +194,7 @@ pub enum ScreenContext {
MoveFocusDown,
MoveFocusUp,
MoveFocusRight,
- Quit,
+ Exit,
ScrollUp,
ScrollDown,
PageScrollUp,
@@ -239,7 +239,7 @@ impl From<&ScreenInstruction> for ScreenContext {
ScreenInstruction::MoveFocusDown => ScreenContext::MoveFocusDown,
ScreenInstruction::MoveFocusUp => ScreenContext::MoveFocusUp,
ScreenInstruction::MoveFocusRight => ScreenContext::MoveFocusRight,
- ScreenInstruction::Quit => ScreenContext::Quit,
+ ScreenInstruction::Exit => ScreenContext::Exit,
ScreenInstruction::ScrollUp => ScreenContext::ScrollUp,
ScreenInstruction::ScrollDown => ScreenContext::ScrollDown,
ScreenInstruction::PageScrollUp => ScreenContext::PageScrollUp,
@@ -276,7 +276,7 @@ pub enum PtyContext {
NewTab,
ClosePane,
CloseTab,
- Quit,
+ Exit,
}
impl From<&PtyInstruction> for PtyContext {
@@ -288,7 +288,7 @@ impl From<&PtyInstruction> for PtyContext {
PtyInstruction::ClosePane(_) => PtyContext::ClosePane,
PtyInstruction::CloseTab(_) => PtyContext::CloseTab,
PtyInstruction::NewTab => PtyContext::NewTab,
- PtyInstruction::Quit => PtyContext::Quit,
+ PtyInstruction::Exit => PtyContext::Exit,
}
}
}
@@ -304,7 +304,7 @@ pub enum PluginContext {
Update,
Render,
Unload,
- Quit,
+ Exit,
}
impl From<&PluginInstruction> for PluginContext {
@@ -314,7 +314,7 @@ impl From<&PluginInstruction> for PluginContext {
PluginInstruction::Update(..) => PluginContext::Update,
PluginInstruction::Render(..) => PluginContext::Render,
PluginInstruction::Unload(_) => PluginContext::Unload,
- PluginInstruction::Quit => PluginContext::Quit,
+ PluginInstruction::Exit => PluginContext::Exit,
}
}
}
diff --git a/src/common/mod.rs b/src/common/mod.rs
index 7e7de23c..3ae95a74 100644
--- a/src/common/mod.rs
+++ b/src/common/mod.rs
@@ -18,7 +18,7 @@ use std::{collections::HashMap, fs};
use crate::panes::PaneId;
use directories_next::ProjectDirs;
use input::handler::InputMode;
-use ipmpsc::{Sender as IpcSender, SharedRingBuffer};
+use ipmpsc::{Receiver as IpcReceiver, Sender as IpcSender, SharedRingBuffer};
use serde::{Deserialize, Serialize};
use termion::input::TermRead;
use wasm_vm::PluginEnv;
@@ -48,10 +48,11 @@ pub enum ServerInstruction {
SplitHorizontally,
SplitVertically,
MoveFocus,
+ NewClient(String),
ToPty(PtyInstruction),
ToScreen(ScreenInstruction),
ClosePluginPane(u32),
- Quit,
+ Exit,
}
#[derive(Serialize, Deserialize, Debug, Clone)]
@@ -59,6 +60,7 @@ pub enum ClientInstruction {
ToScreen(ScreenInstruction),
ClosePluginPane(u32),
Error(String),
+ Exit,
}
// FIXME: It would be good to add some more things to this over time
@@ -177,6 +179,19 @@ pub enum AppInstruction {
ToPlugin(PluginInstruction),
}
+impl From<ClientInstruction> for AppInstruction {
+ fn from(item: ClientInstruction) -> Self {
+ match item {
+ ClientInstruction::ToScreen(s) => AppInstruction::ToScreen(s),
+ ClientInstruction::Error(e) => AppInstruction::Error(e),
+ ClientInstruction::ClosePluginPane(p) => {
+ AppInstruction::ToPlugin(PluginInstruction::Unload(p))
+ }
+ ClientInstruction::Exit => AppInstruction::Exit,
+ }
+ }
+}
+
/// Start Zellij with the specified [`OsApi`] and command-line arguments.
// FIXME this should definitely be modularized and split into different functions.
pub fn start(mut os_input: Box<dyn OsApi>, opts: CliArgs, config: Config) {
@@ -207,15 +222,16 @@ pub fn start(mut os_input: Box<dyn OsApi>, opts: CliArgs, config: Config) {
let (send_app_instructions, receive_app_instructions): SyncChannelWithContext<AppInstruction> =
mpsc::sync_channel(500);
- let send_app_instructions =
- SenderWithContext::new(SenderType::SyncSender(send_app_instructions));
+ let mut send_app_instructions =
+ SenderWithContext::new(err_ctx, SenderType::SyncSender(send_app_instructions));
- let ipc_thread = start_server(
- os_input.clone(),
- opts.clone(),
- command_is_executing.clone(),
- send_app_instructions.clone(),
- );
+ let ipc_thread = start_server(os_input.clone(), opts.clone(), command_is_executing.clone());
+
+ let (client_buffer_path, client_buffer) = SharedRingBuffer::create_temp(8192).unwrap();
+ let mut send_server_instructions = IpcSenderWithContext::to_server();
+ send_server_instructions
+ .send(ServerInstruction::NewClient(client_buffer_path))
+ .unwrap();
#[cfg(not(test))]
std::panic::set_hook({
@@ -405,26 +421,7 @@ pub fn start(mut os_input: Box<dyn OsApi>, opts: CliArgs, config: Config) {
screen.apply_layout(Layout::new(layout), new_pane_pids);
command_is_executing.done_opening_new_pane();
}
- ScreenInstruction::GoToTab(tab_index) => {
- screen.go_to_tab(tab_index as usize)
- }
- ScreenInstruction::UpdateTabName(c) => {
- screen.update_active_tab_name(c);
- }
- ScreenInstruction::TerminalResize => {
- screen.resize_to_screen();
- }
- ScreenInstruction::ChangeMode(mode_info) => {
- screen.change_mode(mode_info);
- }
- ScreenInstruction::ToggleActiveSyncPanes => {
- screen
- .get_active_tab_mut()
- .unwrap()
- .toggle_sync_panes_is_active();
- screen.update_tabs();
- }
- ScreenInstruction::Quit => {
+ ScreenInstruction::Exit => {
break;
}
}
@@ -525,7 +522,7 @@ pub fn start(mut os_input: Box<dyn OsApi>, opts: CliArgs, config: Config) {
buf_tx.send(wasi_read_string(&plugin_env.wasi_env)).unwrap();
}
PluginInstruction::Unload(pid) => drop(plugin_map.remove(&pid)),
- PluginInstruction::Quit => break,
+ PluginInstruction::Exit => break,
}
}
})
@@ -536,6 +533,7 @@ pub fn start(mut os_input: Box<dyn OsApi>, opts: CliArgs, config: Config) {
.spawn({
let send_screen_instructions = send_screen_instructions.clone();
let send_plugin_instructions = send_plugin_instructions.clone();
+ let send_app_instructions = send_app_instructions.clone();
let os_input = os_input.clone();
let config = config;
move || {
@@ -550,7 +548,25 @@ pub fn start(mut os_input: Box<dyn OsApi>, opts: CliArgs, config: Config) {
}
});
- let mut send_server_instructions = IpcSenderWithContext::to_server();
+ let router_thread = thread::Builder::new()
+ .name("router".to_string())
+ .spawn({
+ let recv_client_instructions = IpcReceiver::new(client_buffer);
+ move || loop {
+ let (err_ctx, instruction): (ErrorContext, ClientInstruction) =
+ recv_client_instructions.recv().unwrap();
+ send_app_instructions.update(err_ctx);
+ match instruction {
+ ClientInstruction::Exit => break,
+ _ => {
+ send_app_instructions
+ .send(AppInstruction::from(instruction))
+ .unwrap();
+ }
+ }
+ }
+ })
+ .unwrap();
#[warn(clippy::never_loop)]
loop {
@@ -562,16 +578,17 @@ pub fn start(mut os_input: Box<dyn OsApi>, opts: CliArgs, config: Config) {
send_screen_instructions.update(err_ctx);
send_server_instructions.update(err_ctx);
match app_instruction {
- AppInstruction::Exit => {
- break;
- }
+ AppInstruction::GetState(state_tx) => drop(state_tx.send(app_state.clone())),
+ AppInstruction::SetState(state) => app_state = state,
+ AppInstruction::Exit => break,
AppInstruction::Error(backtrace) => {
- let _ = send_server_instructions.send(ServerInstruction::Quit);
- let _ = send_screen_instructions.send(ScreenInstruction::Quit);
- let _ = send_plugin_instructions.send(PluginInstruction::Quit);
+ let _ = send_server_instructions.send(ServerInstruction::Exit);
+ let _ = send_screen_instructions.send(ScreenInstruction::Exit);
+ let _ = send_plugin_instructions.send(PluginInstruction::Exit);
let _ = screen_thread.join();
let _ = wasm_thread.join();
let _ = ipc_thread.join();
+ //let _ = router_thread.join();
os_input.unset_raw_mode(0);
let goto_start_of_last_line = format!("\u{1b}[{};{}H", full_screen_ws.rows, 1);
let error = format!("{}\n{}", goto_start_of_last_line, backtrace);
@@ -593,12 +610,13 @@ pub fn start(mut os_input: Box<dyn OsApi>, opts: CliArgs, config: Config) {
}
}
- let _ = send_server_instructions.send(ServerInstruction::Quit);
- let _ = send_screen_instructions.send(ScreenInstruction::Quit);
- let _ = send_plugin_instructions.send(PluginInstruction::Quit);
+ let _ = send_server_instructions.send(ServerInstruction::Exit);
+ let _ = send_screen_instructions.send(ScreenInstruction::Exit);
+ let _ = send_plugin_instructions.send(PluginInstruction::Exit);
screen_thread.join().unwrap();
wasm_thread.join().unwrap();
ipc_thread.join().unwrap();
+ router_thread.join().unwrap();
// cleanup();
let reset_style = "\u{1b}[m";
diff --git a/src/common/pty_bus.rs b/src/common/pty_bus.rs
index 52144454..e08e8576 100644
--- a/src/common/pty_bus.rs
+++ b/src/common/pty_bus.rs
@@ -181,7 +181,7 @@ pub enum PtyInstruction {
NewTab,
ClosePane(PaneId),
CloseTab(Vec<PaneId>),
- Quit,
+ Exit,
}
pub struct PtyBus {
diff --git a/src/common/screen.rs b/src/common/screen.rs
index dc628a4b..7848c243 100644
--- a/src/common/screen.rs
+++ b/src/common/screen.rs
@@ -36,7 +36,7 @@ pub enum ScreenInstruction {
MoveFocusDown,
MoveFocusUp,
MoveFocusRight,
- Quit,
+ Exit,
ScrollUp,
ScrollDown,
PageScrollUp,
diff --git a/src/common/wasm_vm.rs b/src/common/wasm_vm.rs
index ddb7deaf..31b1000c 100644
--- a/src/common/wasm_vm.rs
+++ b/src/common/wasm_vm.rs
@@ -21,7 +21,7 @@ pub enum PluginInstruction {
Update(Option<u32>, Event), // Focused plugin / broadcast, event data
Render(Sender<String>, u32, usize, usize), // String buffer, plugin id, rows, cols
Unload(u32),
- Quit,
+ Exit,
}
#[derive(WasmerEnv, Clone)]
diff --git a/src/server/mod.rs b/src/server/mod.rs
index 27b24736..a39d0bc0 100644
--- a/src/server/mod.rs
+++ b/src/server/mod.rs
@@ -1,19 +1,16 @@
use crate::cli::CliArgs;
use crate::command_is_executing::CommandIsExecuting;
use crate::common::{
- AppInstruction, ChannelWithContext, IpcSenderWithContext, SenderType, SenderWithContext,
+ ChannelWithContext, ClientInstruction, IpcSenderWithContext, SenderType, SenderWithContext,
ServerInstruction,
};
use crate::errors::{ContextType, ErrorContext, PtyContext};
-use crate::layout::Layout;
use crate::os_input_output::OsApi;
use crate::panes::PaneId;
use crate::pty_bus::{PtyBus, PtyInstruction};
use crate::screen::ScreenInstruction;
use crate::utils::consts::ZELLIJ_IPC_PIPE;
-use crate::wasm_vm::PluginInstruction;
-use ipmpsc::{Receiver, SharedRingBuffer};
-use std::io::{BufReader, Read};
+use ipmpsc::{Receiver as IpcReceiver, SharedRingBuffer};
use std::path::PathBuf;
use std::sync::mpsc::channel;
use std::thread;
@@ -22,7 +19,6 @@ pub fn start_server(
os_input: Box<dyn OsApi>,
opts: CliArgs,
command_is_executing: CommandIsExecuting,
- mut send_app_instructions: SenderWithContext<AppInstruction>,
) -> thread::JoinHandle<()> {
let (send_pty_instructions, receive_pty_instructions): ChannelWithContext<PtyInstruction> =
channel();
@@ -31,7 +27,6 @@ pub fn start_server(
SenderType::Sender(send_pty_instructions),
);
- std::fs::remove_file(ZELLIJ_IPC_PIPE).ok();
let server_buffer = SharedRingBuffer::create(ZELLIJ_IPC_PIPE, 8192).unwrap();
// Don't use default layouts in tests, but do everywhere else
@@ -54,7 +49,6 @@ pub fn start_server(
.name("pty".to_string())
.spawn({
let mut command_is_executing = command_is_executing.clone();
- send_pty_instructions.send(PtyInstruction::NewTab).unwrap();
move || loop {
let (event, mut err_ctx) = pty_bus
.receive_pty_instructions
@@ -108,7 +102,7 @@ pub fn start_server(
pty_bus.close_tab(ids);
command_is_executing.done_closing_pane();
}
- PtyInstruction::Quit => {
+ PtyInstruction::Exit => {
break;
}
}
@@ -119,15 +113,20 @@ pub fn start_server(
thread::Builder::new()
.name("ipc_server".to_string())
.spawn({
- let recv_server_instructions = Receiver::new(server_buffer);
+ let recv_server_instructions = IpcReceiver::new(server_buffer);
+ // Fixme: We cannot use uninitialised sender, therefore this Vec.
+ // We make sure that the first message is `NewClient` so there are no out of bouns panics.
+ let mut send_client_instructions: Vec<IpcSenderWithContext> = Vec::with_capacity(1);
move || loop {
- let (mut err_ctx, decoded): (ErrorContext, ServerInstruction) =
+ let (mut err_ctx, instruction): (ErrorContext, ServerInstruction) =
recv_server_instructions.recv().unwrap();
err_ctx.add_call(ContextType::IPCServer);
send_pty_instructions.update(err_ctx);
- send_app_instructions.update(err_ctx);
+ if send_client_instructions.len() == 1 {
+ send_client_instructions[0].update(err_ctx);
+ }
- match decoded {
+ match instruction {
ServerInstruction::OpenFile(file_name) => {
let path = PathBuf::from(file_name);
send_pty_instructions
@@ -145,26 +144,33 @@ pub fn start_server(
.unwrap();
}
ServerInstruction::MoveFocus => {
- send_app_instructions
- .send(AppInstruction::ToScreen(ScreenInstruction::MoveFocus))
+ send_client_instructions[0]
+ .send(ClientInstruction::ToScreen(ScreenInstruction::MoveFocus))
.unwrap();
}
- ServerInstruction::ToPty(instruction) => {
- send_pty_instructions.send(instruction).unwrap();
+ ServerInstruction::NewClient(buffer_path) => {
+ send_pty_instructions.send(PtyInstruction::NewTab).unwrap();
+ send_client_instructions.push(IpcSenderWithContext::new(
+ SharedRingBuffer::open(&buffer_path).unwrap(),
+ ));
+ }
+ ServerInstruction::ToPty(instr) => {
+ send_pty_instructions.send(instr).unwrap();
}
- ServerInstruction::ToScreen(instruction) => {
- send_app_instructions
- .send(AppInstruction::ToScreen(instruction))
+ ServerInstruction::ToScreen(instr) => {
+ send_client_instructions[0]
+ .send(ClientInstruction::ToScreen(instr))
.unwrap();
}
ServerInstruction::ClosePluginPane(pid) => {
- send_app_instructions
- .send(AppInstruction::ToPlugin(PluginInstruction::Unload(pid)))
+ send_client_instructions[0]
+ .send(ClientInstruction::ClosePluginPane(pid))
.unwrap();
}
- ServerInstruction::Quit => {
- let _ = send_pty_instructions.send(PtyInstruction::Quit);
+ ServerInstruction::Exit => {
+ let _ = send_pty_instructions.send(PtyInstruction::Exit);
let _ = pty_thread.join();
+ let _ = send_client_instructions[0].send(ClientInstruction::Exit);
break;
}
}