summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYAMAMOTO Mitsuharu <mituharu@math.s.chiba-u.ac.jp>2011-10-31 12:08:54 +0900
committerYAMAMOTO Mitsuharu <mituharu@math.s.chiba-u.ac.jp>2011-10-31 12:08:54 +0900
commit26edb35c39c32312acb1cc3af7d0ed1c41f6867c (patch)
tree80480e45b04a95598b117363f943682ab580b268
parent1aed9c0d13f9e2551c841b79731e7b2fb781298f (diff)
downloademacs-26edb35c39c32312acb1cc3af7d0ed1c41f6867c.tar.gz
Fix memory leak by y-or-n-p-with-timeout with GUI (Bug#9830).
* xmenu.c (cleanup_widget_value_tree): New function. (xmenu_show, xdialog_show): Use it in record_unwind_protect instead of calling free_menubar_widget_value_tree directly (Bug#9830).
-rw-r--r--src/ChangeLog6
-rw-r--r--src/xmenu.c31
2 files changed, 33 insertions, 4 deletions
diff --git a/src/ChangeLog b/src/ChangeLog
index 218c1615624..674d8a71cf6 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,9 @@
+2011-10-31 YAMAMOTO Mitsuharu <mituharu@math.s.chiba-u.ac.jp>
+
+ * xmenu.c (cleanup_widget_value_tree): New function.
+ (xmenu_show, xdialog_show): Use it in record_unwind_protect instead of
+ calling free_menubar_widget_value_tree directly (Bug#9830).
+
2011-09-19 Andreas Schwab <schwab@linux-m68k.org>
* keymap.c (Fsingle_key_description): Use make_specified_string
diff --git a/src/xmenu.c b/src/xmenu.c
index 5c6c2b0cfdd..bd3aea89e3a 100644
--- a/src/xmenu.c
+++ b/src/xmenu.c
@@ -1658,6 +1658,17 @@ create_and_show_popup_menu (f, first_wv, x, y, for_click, timestamp)
#endif /* not USE_GTK */
+static Lisp_Object
+cleanup_widget_value_tree (Lisp_Object arg)
+{
+ struct Lisp_Save_Value *p = XSAVE_VALUE (arg);
+ widget_value *wv = p->pointer;
+
+ free_menubar_widget_value_tree (wv);
+
+ return Qnil;
+}
+
Lisp_Object
xmenu_show (FRAME_PTR f, int x, int y, int for_click, int keymaps,
Lisp_Object title, char **error, EMACS_UINT timestamp)
@@ -1672,6 +1683,8 @@ xmenu_show (FRAME_PTR f, int x, int y, int for_click, int keymaps,
int first_pane;
+ int specpdl_count = SPECPDL_INDEX ();
+
if (! FRAME_X_P (f))
abort ();
@@ -1866,11 +1879,15 @@ xmenu_show (FRAME_PTR f, int x, int y, int for_click, int keymaps,
/* No selection has been chosen yet. */
menu_item_selection = 0;
+ /* Make sure to free the widget_value objects we used to specify the
+ contents even with longjmp. */
+ record_unwind_protect (cleanup_widget_value_tree,
+ make_save_value (first_wv, 0));
+
/* Actually create and show the menu until popped down. */
create_and_show_popup_menu (f, first_wv, x, y, for_click, timestamp);
- /* Free the widget_value objects we used to specify the contents. */
- free_menubar_widget_value_tree (first_wv);
+ unbind_to (specpdl_count, Qnil);
/* Find the selected item, and its pane, to return
the proper value. */
@@ -2064,6 +2081,8 @@ xdialog_show (f, keymaps, title, header, error_name)
/* 1 means we've seen the boundary between left-hand elts and right-hand. */
int boundary_seen = 0;
+ int specpdl_count = SPECPDL_INDEX ();
+
if (! FRAME_X_P (f))
abort ();
@@ -2177,11 +2196,15 @@ xdialog_show (f, keymaps, title, header, error_name)
/* No selection has been chosen yet. */
menu_item_selection = 0;
+ /* Make sure to free the widget_value objects we used to specify the
+ contents even with longjmp. */
+ record_unwind_protect (cleanup_widget_value_tree,
+ make_save_value (first_wv, 0));
+
/* Actually create and show the dialog. */
create_and_show_dialog (f, first_wv);
- /* Free the widget_value objects we used to specify the contents. */
- free_menubar_widget_value_tree (first_wv);
+ unbind_to (specpdl_count, Qnil);
/* Find the selected item, and its pane, to return
the proper value. */