diff options
| author | Philipp Stephani | 2017-04-22 16:51:44 +0200 |
|---|---|---|
| committer | Philipp Stephani | 2017-06-11 15:24:05 +0200 |
| commit | 8160c7d914882b40badf9eb8e4792da1b313745e (patch) | |
| tree | ff2dfc4192fe6f677f36b3b785b84d87abb2935d /src/emacs-module.c | |
| parent | 9a86966edb5ce760976bd7ce36c92e3b4eb0705d (diff) | |
| download | emacs-8160c7d914882b40badf9eb8e4792da1b313745e.tar.gz emacs-8160c7d914882b40badf9eb8e4792da1b313745e.zip | |
Support threads in modules
Rather than checking for the main thread, check for the current
thread.
* emacs-module.c (check_thread): New function.
(MODULE_FUNCTION_BEGIN_NO_CATCH, module_get_environment)
(module_non_local_exit_check, module_non_local_exit_clear)
(module_non_local_exit_get, module_non_local_exit_signal)
(module_non_local_exit_throw, module_is_not_nil, module_eq): Use it.
Diffstat (limited to 'src/emacs-module.c')
| -rw-r--r-- | src/emacs-module.c | 29 |
1 files changed, 16 insertions, 13 deletions
diff --git a/src/emacs-module.c b/src/emacs-module.c index c0f2c3fcd0f..afb75e351d2 100644 --- a/src/emacs-module.c +++ b/src/emacs-module.c | |||
| @@ -30,6 +30,7 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */ | |||
| 30 | #include "coding.h" | 30 | #include "coding.h" |
| 31 | #include "keyboard.h" | 31 | #include "keyboard.h" |
| 32 | #include "syssignal.h" | 32 | #include "syssignal.h" |
| 33 | #include "thread.h" | ||
| 33 | 34 | ||
| 34 | #include <intprops.h> | 35 | #include <intprops.h> |
| 35 | #include <verify.h> | 36 | #include <verify.h> |
| @@ -94,7 +95,7 @@ struct module_fun_env; | |||
| 94 | static Lisp_Object value_to_lisp (emacs_value); | 95 | static Lisp_Object value_to_lisp (emacs_value); |
| 95 | static emacs_value lisp_to_value (Lisp_Object); | 96 | static emacs_value lisp_to_value (Lisp_Object); |
| 96 | static enum emacs_funcall_exit module_non_local_exit_check (emacs_env *); | 97 | static enum emacs_funcall_exit module_non_local_exit_check (emacs_env *); |
| 97 | static void check_main_thread (void); | 98 | static void check_thread (void); |
| 98 | static void initialize_environment (emacs_env *, struct emacs_env_private *); | 99 | static void initialize_environment (emacs_env *, struct emacs_env_private *); |
| 99 | static void finalize_environment (emacs_env *); | 100 | static void finalize_environment (emacs_env *); |
| 100 | static void finalize_environment_unwind (void *); | 101 | static void finalize_environment_unwind (void *); |
| @@ -181,7 +182,7 @@ static emacs_value const module_nil = 0; | |||
| 181 | 182 | ||
| 182 | 1. The first argument should always be a pointer to emacs_env. | 183 | 1. The first argument should always be a pointer to emacs_env. |
| 183 | 184 | ||
| 184 | 2. Each function should first call check_main_thread. Note that | 185 | 2. Each function should first call check_thread. Note that |
| 185 | this function is a no-op unless Emacs was built with | 186 | this function is a no-op unless Emacs was built with |
| 186 | --enable-checking. | 187 | --enable-checking. |
| 187 | 188 | ||
| @@ -215,7 +216,7 @@ static emacs_value const module_nil = 0; | |||
| 215 | 216 | ||
| 216 | #define MODULE_FUNCTION_BEGIN_NO_CATCH(error_retval) \ | 217 | #define MODULE_FUNCTION_BEGIN_NO_CATCH(error_retval) \ |
| 217 | do { \ | 218 | do { \ |
| 218 | check_main_thread (); \ | 219 | check_thread (); \ |
| 219 | if (module_non_local_exit_check (env) != emacs_funcall_exit_return) \ | 220 | if (module_non_local_exit_check (env) != emacs_funcall_exit_return) \ |
| 220 | return error_retval; \ | 221 | return error_retval; \ |
| 221 | } while (false) | 222 | } while (false) |
| @@ -241,8 +242,9 @@ CHECK_USER_PTR (Lisp_Object obj) | |||
| 241 | static emacs_env * | 242 | static emacs_env * |
| 242 | module_get_environment (struct emacs_runtime *ert) | 243 | module_get_environment (struct emacs_runtime *ert) |
| 243 | { | 244 | { |
| 244 | check_main_thread (); | 245 | emacs_env *env = &ert->private_members->pub; |
| 245 | return &ert->private_members->pub; | 246 | check_thread (); |
| 247 | return env; | ||
| 246 | } | 248 | } |
| 247 | 249 | ||
| 248 | /* To make global refs (GC-protected global values) keep a hash that | 250 | /* To make global refs (GC-protected global values) keep a hash that |
| @@ -303,21 +305,21 @@ module_free_global_ref (emacs_env *env, emacs_value ref) | |||
| 303 | static enum emacs_funcall_exit | 305 | static enum emacs_funcall_exit |
| 304 | module_non_local_exit_check (emacs_env *env) | 306 | module_non_local_exit_check (emacs_env *env) |
| 305 | { | 307 | { |
| 306 | check_main_thread (); | 308 | check_thread (); |
| 307 | return env->private_members->pending_non_local_exit; | 309 | return env->private_members->pending_non_local_exit; |
| 308 | } | 310 | } |
| 309 | 311 | ||
| 310 | static void | 312 | static void |
| 311 | module_non_local_exit_clear (emacs_env *env) | 313 | module_non_local_exit_clear (emacs_env *env) |
| 312 | { | 314 | { |
| 313 | check_main_thread (); | 315 | check_thread (); |
| 314 | env->private_members->pending_non_local_exit = emacs_funcall_exit_return; | 316 | env->private_members->pending_non_local_exit = emacs_funcall_exit_return; |
| 315 | } | 317 | } |
| 316 | 318 | ||
| 317 | static enum emacs_funcall_exit | 319 | static enum emacs_funcall_exit |
| 318 | module_non_local_exit_get (emacs_env *env, emacs_value *sym, emacs_value *data) | 320 | module_non_local_exit_get (emacs_env *env, emacs_value *sym, emacs_value *data) |
| 319 | { | 321 | { |
| 320 | check_main_thread (); | 322 | check_thread (); |
| 321 | struct emacs_env_private *p = env->private_members; | 323 | struct emacs_env_private *p = env->private_members; |
| 322 | if (p->pending_non_local_exit != emacs_funcall_exit_return) | 324 | if (p->pending_non_local_exit != emacs_funcall_exit_return) |
| 323 | { | 325 | { |
| @@ -332,7 +334,7 @@ module_non_local_exit_get (emacs_env *env, emacs_value *sym, emacs_value *data) | |||
| 332 | static void | 334 | static void |
| 333 | module_non_local_exit_signal (emacs_env *env, emacs_value sym, emacs_value data) | 335 | module_non_local_exit_signal (emacs_env *env, emacs_value sym, emacs_value data) |
| 334 | { | 336 | { |
| 335 | check_main_thread (); | 337 | check_thread (); |
| 336 | if (module_non_local_exit_check (env) == emacs_funcall_exit_return) | 338 | if (module_non_local_exit_check (env) == emacs_funcall_exit_return) |
| 337 | module_non_local_exit_signal_1 (env, value_to_lisp (sym), | 339 | module_non_local_exit_signal_1 (env, value_to_lisp (sym), |
| 338 | value_to_lisp (data)); | 340 | value_to_lisp (data)); |
| @@ -341,7 +343,7 @@ module_non_local_exit_signal (emacs_env *env, emacs_value sym, emacs_value data) | |||
| 341 | static void | 343 | static void |
| 342 | module_non_local_exit_throw (emacs_env *env, emacs_value tag, emacs_value value) | 344 | module_non_local_exit_throw (emacs_env *env, emacs_value tag, emacs_value value) |
| 343 | { | 345 | { |
| 344 | check_main_thread (); | 346 | check_thread (); |
| 345 | if (module_non_local_exit_check (env) == emacs_funcall_exit_return) | 347 | if (module_non_local_exit_check (env) == emacs_funcall_exit_return) |
| 346 | module_non_local_exit_throw_1 (env, value_to_lisp (tag), | 348 | module_non_local_exit_throw_1 (env, value_to_lisp (tag), |
| 347 | value_to_lisp (value)); | 349 | value_to_lisp (value)); |
| @@ -724,12 +726,13 @@ module_function_arity (const struct Lisp_Module_Function *const function) | |||
| 724 | /* Helper functions. */ | 726 | /* Helper functions. */ |
| 725 | 727 | ||
| 726 | static void | 728 | static void |
| 727 | check_main_thread (void) | 729 | check_thread (void) |
| 728 | { | 730 | { |
| 731 | eassert (current_thread != NULL); | ||
| 729 | #ifdef HAVE_PTHREAD | 732 | #ifdef HAVE_PTHREAD |
| 730 | eassert (pthread_equal (pthread_self (), main_thread_id)); | 733 | eassert (pthread_equal (pthread_self (), current_thread->thread_id)); |
| 731 | #elif defined WINDOWSNT | 734 | #elif defined WINDOWSNT |
| 732 | eassert (GetCurrentThreadId () == dwMainThreadId); | 735 | eassert (GetCurrentThreadId () == current_thread->thread_id); |
| 733 | #endif | 736 | #endif |
| 734 | } | 737 | } |
| 735 | 738 | ||