diff options
| author | Stefan Monnier | 2006-01-23 02:44:02 +0000 |
|---|---|---|
| committer | Stefan Monnier | 2006-01-23 02:44:02 +0000 |
| commit | 5badc98d737395cbd96188dbbb044ab8dc4da88f (patch) | |
| tree | cec51750b432ed7b57201956f21c68bb24797866 | |
| parent | cfb2f32e41fd97d98129f6bc17991d1b7a906a47 (diff) | |
| download | emacs-5badc98d737395cbd96188dbbb044ab8dc4da88f.tar.gz emacs-5badc98d737395cbd96188dbbb044ab8dc4da88f.zip | |
Avoid allocating Lisp data from code that can be run from a signal handler.
(x_error_message): New var to replace x_error_message_string.
(x_error_catcher, x_catch_errors, x_catch_errors_unwind)
(x_check_errors, x_had_errors_p, x_clear_errors, x_error_handler)
(syms_of_xterm): Use it instead of x_error_message_string.
| -rw-r--r-- | src/ChangeLog | 13 | ||||
| -rw-r--r-- | src/xterm.c | 56 |
2 files changed, 49 insertions, 20 deletions
diff --git a/src/ChangeLog b/src/ChangeLog index 9527dc2bb03..121fe76629e 100644 --- a/src/ChangeLog +++ b/src/ChangeLog | |||
| @@ -1,3 +1,16 @@ | |||
| 1 | 2006-01-22 Stefan Monnier <monnier@iro.umontreal.ca> | ||
| 2 | |||
| 3 | * xterm.c: Avoid allocating Lisp data from a signal handler. | ||
| 4 | (x_error_message): New var to replace x_error_message_string. | ||
| 5 | (x_error_catcher, x_catch_errors, x_catch_errors_unwind) | ||
| 6 | (x_check_errors, x_had_errors_p, x_clear_errors, x_error_handler) | ||
| 7 | (syms_of_xterm): Use it instead of x_error_message_string. | ||
| 8 | |||
| 9 | * alloc.c (lisp_align_free): Add an assertion. | ||
| 10 | (make_interval, allocate_string, make_float, Fcons, Fmake_symbol) | ||
| 11 | (allocate_misc): If ENABLE_CHECKING is on, check we're not called from | ||
| 12 | a signal handler. | ||
| 13 | |||
| 1 | 2006-01-21 Luc Teirlinck <teirllm@auburn.edu> | 14 | 2006-01-21 Luc Teirlinck <teirllm@auburn.edu> |
| 2 | 15 | ||
| 3 | * dired.c (syms_of_dired) <completion-ignored-extensions>: Doc fix. | 16 | * dired.c (syms_of_dired) <completion-ignored-extensions>: Doc fix. |
diff --git a/src/xterm.c b/src/xterm.c index ebcf2cb4def..9b19dbb0f5e 100644 --- a/src/xterm.c +++ b/src/xterm.c | |||
| @@ -1,6 +1,6 @@ | |||
| 1 | /* X Communication module for terminals which understand the X protocol. | 1 | /* X Communication module for terminals which understand the X protocol. |
| 2 | Copyright (C) 1989, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, | 2 | Copyright (C) 1989, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, |
| 3 | 2002, 2003, 2004, 2005 Free Software Foundation, Inc. | 3 | 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc. |
| 4 | 4 | ||
| 5 | This file is part of GNU Emacs. | 5 | This file is part of GNU Emacs. |
| 6 | 6 | ||
| @@ -7458,7 +7458,12 @@ x_text_icon (f, icon_name) | |||
| 7458 | /* If non-nil, this should be a string. | 7458 | /* If non-nil, this should be a string. |
| 7459 | It means catch X errors and store the error message in this string. */ | 7459 | It means catch X errors and store the error message in this string. */ |
| 7460 | 7460 | ||
| 7461 | static Lisp_Object x_error_message_string; | 7461 | struct x_error_message_stack { |
| 7462 | char string[X_ERROR_MESSAGE_SIZE]; | ||
| 7463 | Display *dpy; | ||
| 7464 | struct x_error_message_stack *prev; | ||
| 7465 | }; | ||
| 7466 | static struct x_error_message_stack *x_error_message; | ||
| 7462 | 7467 | ||
| 7463 | /* An X error handler which stores the error message in | 7468 | /* An X error handler which stores the error message in |
| 7464 | x_error_message_string. This is called from x_error_handler if | 7469 | x_error_message_string. This is called from x_error_handler if |
| @@ -7470,7 +7475,7 @@ x_error_catcher (display, error) | |||
| 7470 | XErrorEvent *error; | 7475 | XErrorEvent *error; |
| 7471 | { | 7476 | { |
| 7472 | XGetErrorText (display, error->error_code, | 7477 | XGetErrorText (display, error->error_code, |
| 7473 | SDATA (x_error_message_string), | 7478 | x_error_message->string, |
| 7474 | X_ERROR_MESSAGE_SIZE); | 7479 | X_ERROR_MESSAGE_SIZE); |
| 7475 | } | 7480 | } |
| 7476 | 7481 | ||
| @@ -7495,16 +7500,23 @@ x_catch_errors (dpy) | |||
| 7495 | Display *dpy; | 7500 | Display *dpy; |
| 7496 | { | 7501 | { |
| 7497 | int count = SPECPDL_INDEX (); | 7502 | int count = SPECPDL_INDEX (); |
| 7503 | struct x_error_message_stack *data = malloc (sizeof (*data)); | ||
| 7504 | Lisp_Object dummy; | ||
| 7505 | #ifdef ENABLE_CHECKING | ||
| 7506 | dummy = make_number ((EMACS_INT)dpy + (EMACS_INT)x_error_message); | ||
| 7507 | #else | ||
| 7508 | dummy = Qnil; | ||
| 7509 | #endif | ||
| 7498 | 7510 | ||
| 7499 | /* Make sure any errors from previous requests have been dealt with. */ | 7511 | /* Make sure any errors from previous requests have been dealt with. */ |
| 7500 | XSync (dpy, False); | 7512 | XSync (dpy, False); |
| 7501 | 7513 | ||
| 7502 | record_unwind_protect (x_catch_errors_unwind, | 7514 | data->dpy = dpy; |
| 7503 | Fcons (make_save_value (dpy, 0), | 7515 | data->string[0] = 0; |
| 7504 | x_error_message_string)); | 7516 | data->prev = x_error_message; |
| 7517 | x_error_message = data; | ||
| 7505 | 7518 | ||
| 7506 | x_error_message_string = make_uninit_string (X_ERROR_MESSAGE_SIZE); | 7519 | record_unwind_protect (x_catch_errors_unwind, dummy); |
| 7507 | SSET (x_error_message_string, 0, 0); | ||
| 7508 | 7520 | ||
| 7509 | return count; | 7521 | return count; |
| 7510 | } | 7522 | } |
| @@ -7512,11 +7524,11 @@ x_catch_errors (dpy) | |||
| 7512 | /* Unbind the binding that we made to check for X errors. */ | 7524 | /* Unbind the binding that we made to check for X errors. */ |
| 7513 | 7525 | ||
| 7514 | static Lisp_Object | 7526 | static Lisp_Object |
| 7515 | x_catch_errors_unwind (old_val) | 7527 | x_catch_errors_unwind (dummy) |
| 7516 | Lisp_Object old_val; | 7528 | Lisp_Object dummy; |
| 7517 | { | 7529 | { |
| 7518 | Lisp_Object first = XCAR (old_val); | 7530 | Display *dpy = x_error_message->dpy; |
| 7519 | Display *dpy = XSAVE_VALUE (first)->pointer; | 7531 | struct x_error_message_stack *tmp; |
| 7520 | 7532 | ||
| 7521 | /* The display may have been closed before this function is called. | 7533 | /* The display may have been closed before this function is called. |
| 7522 | Check if it is still open before calling XSync. */ | 7534 | Check if it is still open before calling XSync. */ |
| @@ -7527,7 +7539,12 @@ x_catch_errors_unwind (old_val) | |||
| 7527 | UNBLOCK_INPUT; | 7539 | UNBLOCK_INPUT; |
| 7528 | } | 7540 | } |
| 7529 | 7541 | ||
| 7530 | x_error_message_string = XCDR (old_val); | 7542 | tmp = x_error_message; |
| 7543 | x_error_message = x_error_message->prev; | ||
| 7544 | free (tmp); | ||
| 7545 | |||
| 7546 | eassert (dummy == make_number ((EMACS_INT)dpy + (EMACS_INT)x_error_message)); | ||
| 7547 | |||
| 7531 | return Qnil; | 7548 | return Qnil; |
| 7532 | } | 7549 | } |
| 7533 | 7550 | ||
| @@ -7543,8 +7560,8 @@ x_check_errors (dpy, format) | |||
| 7543 | /* Make sure to catch any errors incurred so far. */ | 7560 | /* Make sure to catch any errors incurred so far. */ |
| 7544 | XSync (dpy, False); | 7561 | XSync (dpy, False); |
| 7545 | 7562 | ||
| 7546 | if (SREF (x_error_message_string, 0)) | 7563 | if (x_error_message->string[0]) |
| 7547 | error (format, SDATA (x_error_message_string)); | 7564 | error (format, x_error_message->string); |
| 7548 | } | 7565 | } |
| 7549 | 7566 | ||
| 7550 | /* Nonzero if we had any X protocol errors | 7567 | /* Nonzero if we had any X protocol errors |
| @@ -7557,7 +7574,7 @@ x_had_errors_p (dpy) | |||
| 7557 | /* Make sure to catch any errors incurred so far. */ | 7574 | /* Make sure to catch any errors incurred so far. */ |
| 7558 | XSync (dpy, False); | 7575 | XSync (dpy, False); |
| 7559 | 7576 | ||
| 7560 | return SREF (x_error_message_string, 0) != 0; | 7577 | return x_error_message->string[0] != 0; |
| 7561 | } | 7578 | } |
| 7562 | 7579 | ||
| 7563 | /* Forget about any errors we have had, since we did x_catch_errors on DPY. */ | 7580 | /* Forget about any errors we have had, since we did x_catch_errors on DPY. */ |
| @@ -7566,7 +7583,7 @@ void | |||
| 7566 | x_clear_errors (dpy) | 7583 | x_clear_errors (dpy) |
| 7567 | Display *dpy; | 7584 | Display *dpy; |
| 7568 | { | 7585 | { |
| 7569 | SSET (x_error_message_string, 0, 0); | 7586 | x_error_message->string[0] = 0; |
| 7570 | } | 7587 | } |
| 7571 | 7588 | ||
| 7572 | /* Stop catching X protocol errors and let them make Emacs die. | 7589 | /* Stop catching X protocol errors and let them make Emacs die. |
| @@ -7748,7 +7765,7 @@ x_error_handler (display, error) | |||
| 7748 | Display *display; | 7765 | Display *display; |
| 7749 | XErrorEvent *error; | 7766 | XErrorEvent *error; |
| 7750 | { | 7767 | { |
| 7751 | if (! NILP (x_error_message_string)) | 7768 | if (x_error_message) |
| 7752 | x_error_catcher (display, error); | 7769 | x_error_catcher (display, error); |
| 7753 | else | 7770 | else |
| 7754 | x_error_quitter (display, error); | 7771 | x_error_quitter (display, error); |
| @@ -10818,8 +10835,7 @@ x_initialize () | |||
| 10818 | void | 10835 | void |
| 10819 | syms_of_xterm () | 10836 | syms_of_xterm () |
| 10820 | { | 10837 | { |
| 10821 | staticpro (&x_error_message_string); | 10838 | x_error_message = NULL; |
| 10822 | x_error_message_string = Qnil; | ||
| 10823 | 10839 | ||
| 10824 | staticpro (&x_display_name_list); | 10840 | staticpro (&x_display_name_list); |
| 10825 | x_display_name_list = Qnil; | 10841 | x_display_name_list = Qnil; |