diff options
| author | Philipp Stephani | 2019-01-02 22:04:56 +0100 |
|---|---|---|
| committer | Philipp Stephani | 2019-02-24 22:43:07 +0100 |
| commit | 72ec233f2a1b8a6a9574e61588d0467caf41755c (patch) | |
| tree | 725add4413feb9cb7789576294099096e63d3044 /src | |
| parent | 5653b76d0bacf1edfc3d962c0bb991344cd80f6f (diff) | |
| download | emacs-72ec233f2a1b8a6a9574e61588d0467caf41755c.tar.gz emacs-72ec233f2a1b8a6a9574e61588d0467caf41755c.zip | |
Ignore pending_signals when checking for quits.
pending_signals is often set if no quit is pending. This results in
bugs in module code if the module returns but no quit is actually
pending.
As a better alternative, add a new process_input environment function
for Emacs 27. That function processes signals (like maybe_quit).
* configure.ac: Add module snippet for Emacs 27.
* src/module-env-27.h: New file.
* src/emacs-module.h.in: Add process_input function to environment
interface.
* src/emacs-module.c (module_should_quit): Use QUITP macro to check
whether the caller should quit.
(module_process_input): New function.
(initialize_environment): Use it.
* src/eval.c: Remove obsolete comment.
* test/data/emacs-module/mod-test.c (signal_wrong_type_argument)
(signal_errno): New helper functions.
(Fmod_test_sleep_until): New test module function.
* test/src/emacs-module-tests.el (mod-test-sleep-until): New unit
test.
* doc/lispref/internals.texi (Module Misc): Document process_input.
Diffstat (limited to 'src')
| -rw-r--r-- | src/emacs-module.c | 15 | ||||
| -rw-r--r-- | src/emacs-module.h.in | 21 | ||||
| -rw-r--r-- | src/eval.c | 5 | ||||
| -rw-r--r-- | src/module-env-27.h | 4 |
4 files changed, 37 insertions, 8 deletions
diff --git a/src/emacs-module.c b/src/emacs-module.c index cbab0234201..b70d6cea812 100644 --- a/src/emacs-module.c +++ b/src/emacs-module.c | |||
| @@ -671,13 +671,21 @@ module_vec_size (emacs_env *env, emacs_value vec) | |||
| 671 | return ASIZE (lvec); | 671 | return ASIZE (lvec); |
| 672 | } | 672 | } |
| 673 | 673 | ||
| 674 | /* This function should return true if and only if maybe_quit would do | 674 | /* This function should return true if and only if maybe_quit would |
| 675 | anything. */ | 675 | quit. */ |
| 676 | static bool | 676 | static bool |
| 677 | module_should_quit (emacs_env *env) | 677 | module_should_quit (emacs_env *env) |
| 678 | { | 678 | { |
| 679 | MODULE_FUNCTION_BEGIN_NO_CATCH (false); | 679 | MODULE_FUNCTION_BEGIN_NO_CATCH (false); |
| 680 | return (! NILP (Vquit_flag) && NILP (Vinhibit_quit)) || pending_signals; | 680 | return QUITP; |
| 681 | } | ||
| 682 | |||
| 683 | static enum emacs_process_input_result | ||
| 684 | module_process_input (emacs_env *env) | ||
| 685 | { | ||
| 686 | MODULE_FUNCTION_BEGIN (emacs_process_input_quit); | ||
| 687 | maybe_quit (); | ||
| 688 | return emacs_process_input_continue; | ||
| 681 | } | 689 | } |
| 682 | 690 | ||
| 683 | 691 | ||
| @@ -1082,6 +1090,7 @@ initialize_environment (emacs_env *env, struct emacs_env_private *priv) | |||
| 1082 | env->vec_get = module_vec_get; | 1090 | env->vec_get = module_vec_get; |
| 1083 | env->vec_size = module_vec_size; | 1091 | env->vec_size = module_vec_size; |
| 1084 | env->should_quit = module_should_quit; | 1092 | env->should_quit = module_should_quit; |
| 1093 | env->process_input = module_process_input; | ||
| 1085 | Vmodule_environments = Fcons (make_mint_ptr (env), Vmodule_environments); | 1094 | Vmodule_environments = Fcons (make_mint_ptr (env), Vmodule_environments); |
| 1086 | return env; | 1095 | return env; |
| 1087 | } | 1096 | } |
diff --git a/src/emacs-module.h.in b/src/emacs-module.h.in index 4c5286f6257..009d1583fef 100644 --- a/src/emacs-module.h.in +++ b/src/emacs-module.h.in | |||
| @@ -47,7 +47,7 @@ extern "C" { | |||
| 47 | #endif | 47 | #endif |
| 48 | 48 | ||
| 49 | /* Current environment. */ | 49 | /* Current environment. */ |
| 50 | typedef struct emacs_env_26 emacs_env; | 50 | typedef struct emacs_env_27 emacs_env; |
| 51 | 51 | ||
| 52 | /* Opaque pointer representing an Emacs Lisp value. | 52 | /* Opaque pointer representing an Emacs Lisp value. |
| 53 | BEWARE: Do not assume NULL is a valid value! */ | 53 | BEWARE: Do not assume NULL is a valid value! */ |
| @@ -83,6 +83,16 @@ enum emacs_funcall_exit | |||
| 83 | emacs_funcall_exit_throw = 2 | 83 | emacs_funcall_exit_throw = 2 |
| 84 | }; | 84 | }; |
| 85 | 85 | ||
| 86 | /* Possible return values for emacs_env.process_input. */ | ||
| 87 | enum emacs_process_input_result | ||
| 88 | { | ||
| 89 | /* Module code may continue */ | ||
| 90 | emacs_process_input_continue = 0, | ||
| 91 | |||
| 92 | /* Module code should return control to Emacs as soon as possible. */ | ||
| 93 | emacs_process_input_quit = 1 | ||
| 94 | }; | ||
| 95 | |||
| 86 | struct emacs_env_25 | 96 | struct emacs_env_25 |
| 87 | { | 97 | { |
| 88 | @module_env_snippet_25@ | 98 | @module_env_snippet_25@ |
| @@ -95,6 +105,15 @@ struct emacs_env_26 | |||
| 95 | @module_env_snippet_26@ | 105 | @module_env_snippet_26@ |
| 96 | }; | 106 | }; |
| 97 | 107 | ||
| 108 | struct emacs_env_27 | ||
| 109 | { | ||
| 110 | @module_env_snippet_25@ | ||
| 111 | |||
| 112 | @module_env_snippet_26@ | ||
| 113 | |||
| 114 | @module_env_snippet_27@ | ||
| 115 | }; | ||
| 116 | |||
| 98 | /* Every module should define a function as follows. */ | 117 | /* Every module should define a function as follows. */ |
| 99 | extern int emacs_module_init (struct emacs_runtime *ert) | 118 | extern int emacs_module_init (struct emacs_runtime *ert) |
| 100 | EMACS_NOEXCEPT | 119 | EMACS_NOEXCEPT |
diff --git a/src/eval.c b/src/eval.c index b094fc2e663..b6cdfc911d0 100644 --- a/src/eval.c +++ b/src/eval.c | |||
| @@ -1575,10 +1575,7 @@ process_quit_flag (void) | |||
| 1575 | If quit-flag is set to `kill-emacs' the SIGINT handler has received | 1575 | If quit-flag is set to `kill-emacs' the SIGINT handler has received |
| 1576 | a request to exit Emacs when it is safe to do. | 1576 | a request to exit Emacs when it is safe to do. |
| 1577 | 1577 | ||
| 1578 | When not quitting, process any pending signals. | 1578 | When not quitting, process any pending signals. */ |
| 1579 | |||
| 1580 | If you change this function, also adapt module_should_quit in | ||
| 1581 | emacs-module.c. */ | ||
| 1582 | 1579 | ||
| 1583 | void | 1580 | void |
| 1584 | maybe_quit (void) | 1581 | maybe_quit (void) |
diff --git a/src/module-env-27.h b/src/module-env-27.h new file mode 100644 index 00000000000..b491b60fbbc --- /dev/null +++ b/src/module-env-27.h | |||
| @@ -0,0 +1,4 @@ | |||
| 1 | /* Processes pending input events and returns whether the module | ||
| 2 | function should quit. */ | ||
| 3 | enum emacs_process_input_result (*process_input) (emacs_env *env) | ||
| 4 | EMACS_ATTRIBUTE_NONNULL (1); | ||