diff options
author | YAMAMOTO Mitsuharu <mituharu@math.s.chiba-u.ac.jp> | 2011-10-31 12:08:54 +0900 |
---|---|---|
committer | YAMAMOTO Mitsuharu <mituharu@math.s.chiba-u.ac.jp> | 2011-10-31 12:08:54 +0900 |
commit | ba24cea25940796868dc0d1a6752f9279613b3d7 (patch) | |
tree | 010b295d0f58a0640cf44d30c0a951f8f58d9af3 /src/xmenu.c | |
parent | fa2ec41ffd2cace14f37f5d18d986b410cb038a1 (diff) | |
download | emacs-ba24cea25940796868dc0d1a6752f9279613b3d7.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).
Diffstat (limited to 'src/xmenu.c')
-rw-r--r-- | src/xmenu.c | 31 |
1 files changed, 27 insertions, 4 deletions
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. */ |