summaryrefslogtreecommitdiff
path: root/clients
diff options
context:
space:
mode:
authorDima Ryazanov <dima@gmail.com>2012-11-29 00:27:09 -0800
committerKristian Høgsberg <krh@bitplanet.net>2012-11-30 14:11:41 -0500
commita85292e73c0bb9fca46e123c92c6f6550c57924d (patch)
tree486e1a7a55f9f090a5764e631fc23a0979178d2b /clients
parentcd1d6c8f1994b0d055eba168a891f4e26837ae40 (diff)
Fix a crash when opening two terminal windows and closing the first one.
To reproduce, launch the terminal, open a second window using Ctrl-Shift-N, go back to the first window, and press Ctrl-D. The terminal's master FD gets events even after being closed, causing terminal_destroy to be called twice on the same object. To fix this, I'm adding a function to stop watching an FD.
Diffstat (limited to 'clients')
-rw-r--r--clients/terminal.c6
-rw-r--r--clients/window.c6
-rw-r--r--clients/window.h3
3 files changed, 13 insertions, 2 deletions
diff --git a/clients/terminal.c b/clients/terminal.c
index 1887829..25acc81 100644
--- a/clients/terminal.c
+++ b/clients/terminal.c
@@ -2578,13 +2578,15 @@ terminal_create(struct display *display)
static void
terminal_destroy(struct terminal *terminal)
{
+ display_unwatch_fd(terminal->display, terminal->master);
window_destroy(terminal->window);
close(terminal->master);
wl_list_remove(&terminal->link);
- free(terminal);
if (wl_list_empty(&terminal_list))
- exit(0);
+ display_exit(terminal->display);
+
+ free(terminal);
}
static void
diff --git a/clients/window.c b/clients/window.c
index 3469fe6..b625516 100644
--- a/clients/window.c
+++ b/clients/window.c
@@ -4347,6 +4347,12 @@ display_watch_fd(struct display *display,
}
void
+display_unwatch_fd(struct display *display, int fd)
+{
+ epoll_ctl(display->epoll_fd, EPOLL_CTL_DEL, fd, NULL);
+}
+
+void
display_run(struct display *display)
{
struct task *task;
diff --git a/clients/window.h b/clients/window.h
index 9b820a0..804eef5 100644
--- a/clients/window.h
+++ b/clients/window.h
@@ -147,6 +147,9 @@ display_watch_fd(struct display *display,
int fd, uint32_t events, struct task *task);
void
+display_unwatch_fd(struct display *display, int fd);
+
+void
display_run(struct display *d);
void