Skip to content

Commit

Permalink
Actually fix the race and panics on shutdown
Browse files Browse the repository at this point in the history
2458df9 was a move in the right direction, but it wasn't enough. We need
to do same thing for the conn event listers too.

Basically the UI task relies on the UI event channel being dropped on
the sender side. That happens when we do C-c, and UI task returns.

Similarly connection tasks now relies on the conn chans being dropped.
Clients now return after sending Quit message (same as before), and we
no longer need a Closed message to send the connection event listener
tasks.
  • Loading branch information
osa1 committed Jan 8, 2020
1 parent 02e8924 commit cb6c6c1
Show file tree
Hide file tree
Showing 3 changed files with 5 additions and 24 deletions.
13 changes: 1 addition & 12 deletions libtiny_client/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -98,10 +98,6 @@ pub enum Event {
NickChange(String),
/// A message from the server
Msg(wire::Msg),

/// This is to signal the task that listens for events to stop.
// TODO: Maybe try something like making Client non-Clone and sharing Weaks with tasks
Closed,
}

impl From<StreamError> for Event {
Expand All @@ -127,10 +123,6 @@ pub struct Client {
/// Reference to the state, to be able to provide methods like `get_nick` and
/// `is_nick_accepted`.
state: State,
// We can't have a channel to the sender task directly here, because when the sender task
// returns we lose the receiving end of the channel and there's no way to avoid this except
// with annoying hacks like wrapping it with an `Arc<Mutex<..>>` or something.
snd_ev: mpsc::Sender<Event>,
}

impl Client {
Expand Down Expand Up @@ -249,7 +241,6 @@ impl Client {
pub fn quit(&mut self, reason: Option<String>) {
debug!("quit cmd received");
self.msg_chan.try_send(Cmd::Quit(reason)).unwrap();
self.snd_ev.try_send(Event::Closed).unwrap();
}

/// Get all nicks in a channel.
Expand Down Expand Up @@ -283,7 +274,6 @@ fn connect(server_info: ServerInfo) -> (Client, mpsc::Receiver<Event>) {

// Channel for returning IRC events to user.
let (snd_ev, rcv_ev) = mpsc::channel::<Event>(100);
let snd_ev_clone = snd_ev.clone(); // for Client

// Channel for commands from user.
let (snd_cmd, rcv_cmd) = mpsc::channel::<Cmd>(100);
Expand All @@ -303,7 +293,6 @@ fn connect(server_info: ServerInfo) -> (Client, mpsc::Receiver<Event>) {
msg_chan: snd_cmd,
serv_name,
state: irc_state,
snd_ev: snd_ev_clone,
},
rcv_ev,
)
Expand Down Expand Up @@ -395,7 +384,7 @@ async fn main_loop(

if addrs.is_empty() {
snd_ev.send(Event::CantResolveAddr).await.unwrap();
break; // returns
return;
}

debug!("Address resolved: {:?}", addrs);
Expand Down
6 changes: 2 additions & 4 deletions termbox/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -184,8 +184,7 @@ impl Termbox {
self.output_buffer
.extend_from_slice(termion::clear::All.as_ref());
// T_EXIT_CA for xterm
self.output_buffer
.extend_from_slice(b"\x1b[?1049l");
self.output_buffer.extend_from_slice(b"\x1b[?1049l");

self.flush_output_buffer();
}
Expand Down Expand Up @@ -458,8 +457,7 @@ impl Drop for Termbox {
self.output_buffer
.extend_from_slice(termion::clear::All.as_ref());
// T_EXIT_CA for xterm
self.output_buffer
.extend_from_slice(b"\x1b[?1049l");
self.output_buffer.extend_from_slice(b"\x1b[?1049l");
self.flush_output_buffer();

unsafe {
Expand Down
10 changes: 2 additions & 8 deletions tiny/src/conn.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,14 +15,12 @@ pub(crate) async fn task(
client: Client,
) {
while let Some(ev) = rcv_ev.next().await {
if handle_conn_ev(&*ui, &client, ev) {
return;
}
handle_conn_ev(&*ui, &client, ev);
ui.draw();
}
}

fn handle_conn_ev(ui: &dyn UI, client: &Client, ev: libtiny_client::Event) -> bool {
fn handle_conn_ev(ui: &dyn UI, client: &Client, ev: libtiny_client::Event) {
use libtiny_client::Event::*;
match ev {
ResolvingHost => {
Expand Down Expand Up @@ -104,11 +102,7 @@ fn handle_conn_ev(ui: &dyn UI, client: &Client, ev: libtiny_client::Event) -> bo
Msg(msg) => {
handle_irc_msg(ui, client, msg);
}
Closed => {
return true;
}
}
false
}

fn handle_irc_msg(ui: &dyn UI, client: &Client, msg: wire::Msg) {
Expand Down

0 comments on commit cb6c6c1

Please sign in to comment.