diff options
| author | YAMAMOTO Mitsuharu | 2011-10-31 12:08:54 +0900 |
|---|---|---|
| committer | YAMAMOTO Mitsuharu | 2011-10-31 12:08:54 +0900 |
| commit | ba24cea25940796868dc0d1a6752f9279613b3d7 (patch) | |
| tree | 010b295d0f58a0640cf44d30c0a951f8f58d9af3 /src | |
| parent | fa2ec41ffd2cace14f37f5d18d986b410cb038a1 (diff) | |
| download | emacs-ba24cea25940796868dc0d1a6752f9279613b3d7.tar.gz emacs-ba24cea25940796868dc0d1a6752f9279613b3d7.zip | |
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')
| -rw-r--r-- | src/ChangeLog | 6 | ||||
| -rw-r--r-- | src/xmenu.c | 31 |
2 files changed, 33 insertions, 4 deletions
diff --git a/src/ChangeLog b/src/ChangeLog index 458e8c89821..d006f58b8b6 100644 --- a/src/ChangeLog +++ b/src/ChangeLog | |||
| @@ -1,3 +1,9 @@ | |||
| 1 | 2011-10-31 YAMAMOTO Mitsuharu <mituharu@math.s.chiba-u.ac.jp> | ||
| 2 | |||
| 3 | * xmenu.c (cleanup_widget_value_tree): New function. | ||
| 4 | (xmenu_show, xdialog_show): Use it in record_unwind_protect instead of | ||
| 5 | calling free_menubar_widget_value_tree directly (Bug#9830). | ||
| 6 | |||
| 1 | 2011-09-19 Andreas Schwab <schwab@linux-m68k.org> | 7 | 2011-09-19 Andreas Schwab <schwab@linux-m68k.org> |
| 2 | 8 | ||
| 3 | * keymap.c (Fsingle_key_description): Use make_specified_string | 9 | * 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) | |||
| 1658 | 1658 | ||
| 1659 | #endif /* not USE_GTK */ | 1659 | #endif /* not USE_GTK */ |
| 1660 | 1660 | ||
| 1661 | static Lisp_Object | ||
| 1662 | cleanup_widget_value_tree (Lisp_Object arg) | ||
| 1663 | { | ||
| 1664 | struct Lisp_Save_Value *p = XSAVE_VALUE (arg); | ||
| 1665 | widget_value *wv = p->pointer; | ||
| 1666 | |||
| 1667 | free_menubar_widget_value_tree (wv); | ||
| 1668 | |||
| 1669 | return Qnil; | ||
| 1670 | } | ||
| 1671 | |||
| 1661 | Lisp_Object | 1672 | Lisp_Object |
| 1662 | xmenu_show (FRAME_PTR f, int x, int y, int for_click, int keymaps, | 1673 | xmenu_show (FRAME_PTR f, int x, int y, int for_click, int keymaps, |
| 1663 | Lisp_Object title, char **error, EMACS_UINT timestamp) | 1674 | 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, | |||
| 1672 | 1683 | ||
| 1673 | int first_pane; | 1684 | int first_pane; |
| 1674 | 1685 | ||
| 1686 | int specpdl_count = SPECPDL_INDEX (); | ||
| 1687 | |||
| 1675 | if (! FRAME_X_P (f)) | 1688 | if (! FRAME_X_P (f)) |
| 1676 | abort (); | 1689 | abort (); |
| 1677 | 1690 | ||
| @@ -1866,11 +1879,15 @@ xmenu_show (FRAME_PTR f, int x, int y, int for_click, int keymaps, | |||
| 1866 | /* No selection has been chosen yet. */ | 1879 | /* No selection has been chosen yet. */ |
| 1867 | menu_item_selection = 0; | 1880 | menu_item_selection = 0; |
| 1868 | 1881 | ||
| 1882 | /* Make sure to free the widget_value objects we used to specify the | ||
| 1883 | contents even with longjmp. */ | ||
| 1884 | record_unwind_protect (cleanup_widget_value_tree, | ||
| 1885 | make_save_value (first_wv, 0)); | ||
| 1886 | |||
| 1869 | /* Actually create and show the menu until popped down. */ | 1887 | /* Actually create and show the menu until popped down. */ |
| 1870 | create_and_show_popup_menu (f, first_wv, x, y, for_click, timestamp); | 1888 | create_and_show_popup_menu (f, first_wv, x, y, for_click, timestamp); |
| 1871 | 1889 | ||
| 1872 | /* Free the widget_value objects we used to specify the contents. */ | 1890 | unbind_to (specpdl_count, Qnil); |
| 1873 | free_menubar_widget_value_tree (first_wv); | ||
| 1874 | 1891 | ||
| 1875 | /* Find the selected item, and its pane, to return | 1892 | /* Find the selected item, and its pane, to return |
| 1876 | the proper value. */ | 1893 | the proper value. */ |
| @@ -2064,6 +2081,8 @@ xdialog_show (f, keymaps, title, header, error_name) | |||
| 2064 | /* 1 means we've seen the boundary between left-hand elts and right-hand. */ | 2081 | /* 1 means we've seen the boundary between left-hand elts and right-hand. */ |
| 2065 | int boundary_seen = 0; | 2082 | int boundary_seen = 0; |
| 2066 | 2083 | ||
| 2084 | int specpdl_count = SPECPDL_INDEX (); | ||
| 2085 | |||
| 2067 | if (! FRAME_X_P (f)) | 2086 | if (! FRAME_X_P (f)) |
| 2068 | abort (); | 2087 | abort (); |
| 2069 | 2088 | ||
| @@ -2177,11 +2196,15 @@ xdialog_show (f, keymaps, title, header, error_name) | |||
| 2177 | /* No selection has been chosen yet. */ | 2196 | /* No selection has been chosen yet. */ |
| 2178 | menu_item_selection = 0; | 2197 | menu_item_selection = 0; |
| 2179 | 2198 | ||
| 2199 | /* Make sure to free the widget_value objects we used to specify the | ||
| 2200 | contents even with longjmp. */ | ||
| 2201 | record_unwind_protect (cleanup_widget_value_tree, | ||
| 2202 | make_save_value (first_wv, 0)); | ||
| 2203 | |||
| 2180 | /* Actually create and show the dialog. */ | 2204 | /* Actually create and show the dialog. */ |
| 2181 | create_and_show_dialog (f, first_wv); | 2205 | create_and_show_dialog (f, first_wv); |
| 2182 | 2206 | ||
| 2183 | /* Free the widget_value objects we used to specify the contents. */ | 2207 | unbind_to (specpdl_count, Qnil); |
| 2184 | free_menubar_widget_value_tree (first_wv); | ||
| 2185 | 2208 | ||
| 2186 | /* Find the selected item, and its pane, to return | 2209 | /* Find the selected item, and its pane, to return |
| 2187 | the proper value. */ | 2210 | the proper value. */ |