aboutsummaryrefslogtreecommitdiffstats
path: root/test/data/emacs-module/mod-test.c
diff options
context:
space:
mode:
authorPhilipp Stephani2020-11-27 19:08:55 +0100
committerPhilipp Stephani2020-11-27 21:44:05 +0100
commitcdc632fbe6e149318147a98cccf1b7af191f2ce8 (patch)
tree152ad8041a4b7fbea2bececdae1dd129b1dacc20 /test/data/emacs-module/mod-test.c
parentc9160bda7889d9e37a9b82ef64bf711ba7e32e41 (diff)
downloademacs-cdc632fbe6e149318147a98cccf1b7af191f2ce8.tar.gz
emacs-cdc632fbe6e149318147a98cccf1b7af191f2ce8.zip
Fix incorrect handling of module runtime and environment pointers.
We used to store module runtime and environment pointers in the static lists Vmodule_runtimes and Vmodule_environments. However, this is incorrect because these objects have to be kept per-thread. With this naive approach, interleaving module function calls in separate threads leads to environments being removed in the wrong order, which in turn can cause local module values to be incorrectly garbage-collected. Instead, turn Vmodule_runtimes and Vmodule_environments into hashtables keyed by the thread objects. The fix is relatively localized and should therefore be safe enough for the release branch. Module assertions now have to walk the pointer list for the current thread, which is more correct since they now only find environments for the current thread. Also add a unit test that exemplifies the problem. It interleaves two module calls in two threads so that the first call ends while the second one is still active. Without this change, this test triggers an assertion failure. * src/emacs-module.c (Fmodule_load, initialize_environment) (finalize_environment, finalize_runtime_unwind): Store runtime and environment pointers in per-thread lists. (syms_of_module): Initialize runtimes and environments hashtables. (module_assert_runtime, module_assert_env, value_to_lisp): Consider only objects for the current thread. (module_gc_hash_table_size, module_hash_push, module_hash_pop): New generic hashtable helper functions. (module_objects, module_push_pointer, module_pop_pointer): New helper functions to main thread-specific lists of runtime and environment pointers. (mark_modules): Mark all environments in all threads. * test/data/emacs-module/mod-test.c (Fmod_test_funcall): New test function. (emacs_module_init): Bind it. * test/src/emacs-module-tests.el (emacs-module-tests--variable): New helper type to guard access to state in a thread-safe way. (emacs-module-tests--wait-for-variable) (emacs-module-tests--change-variable): New helper functions. (emacs-module-tests/interleaved-threads): New unit test.
Diffstat (limited to '')
-rw-r--r--test/data/emacs-module/mod-test.c10
1 files changed, 10 insertions, 0 deletions
diff --git a/test/data/emacs-module/mod-test.c b/test/data/emacs-module/mod-test.c
index 8d1b421bb40..528b4b4c582 100644
--- a/test/data/emacs-module/mod-test.c
+++ b/test/data/emacs-module/mod-test.c
@@ -547,6 +547,14 @@ Fmod_test_double (emacs_env *env, ptrdiff_t nargs, emacs_value *args,
547 return result; 547 return result;
548} 548}
549 549
550static emacs_value
551Fmod_test_funcall (emacs_env *env, ptrdiff_t nargs, emacs_value *args,
552 void *data)
553{
554 assert (0 < nargs);
555 return env->funcall (env, args[0], nargs - 1, args + 1);
556}
557
550/* Lisp utilities for easier readability (simple wrappers). */ 558/* Lisp utilities for easier readability (simple wrappers). */
551 559
552/* Provide FEATURE to Emacs. */ 560/* Provide FEATURE to Emacs. */
@@ -629,6 +637,8 @@ emacs_module_init (struct emacs_runtime *ert)
629 DEFUN ("mod-test-add-nanosecond", Fmod_test_add_nanosecond, 1, 1, NULL, NULL); 637 DEFUN ("mod-test-add-nanosecond", Fmod_test_add_nanosecond, 1, 1, NULL, NULL);
630 DEFUN ("mod-test-nanoseconds", Fmod_test_nanoseconds, 1, 1, NULL, NULL); 638 DEFUN ("mod-test-nanoseconds", Fmod_test_nanoseconds, 1, 1, NULL, NULL);
631 DEFUN ("mod-test-double", Fmod_test_double, 1, 1, NULL, NULL); 639 DEFUN ("mod-test-double", Fmod_test_double, 1, 1, NULL, NULL);
640 DEFUN ("mod-test-funcall", Fmod_test_funcall, 1, emacs_variadic_function,
641 NULL, NULL);
632 642
633#undef DEFUN 643#undef DEFUN
634 644