diff options
| author | Stefan Monnier | 2022-02-12 15:25:53 -0500 |
|---|---|---|
| committer | Stefan Monnier | 2022-02-12 15:25:53 -0500 |
| commit | b8460fcb8c320ea6d7449f37f07502d10eb74cd5 (patch) | |
| tree | 49eed9555d20693eb01321881204dd9bc45176d1 /test/src | |
| parent | 89bb5a5f357e911aeb0b9f14e8b2f7c5a5fbabf7 (diff) | |
| download | emacs-b8460fcb8c320ea6d7449f37f07502d10eb74cd5.tar.gz emacs-b8460fcb8c320ea6d7449f37f07502d10eb74cd5.zip | |
Rewrite thread context switch code (bug#48990)
Make the context switch code handle buffer-local variables more
correctly by reusing the code originally written for `backtrace-eval`.
This has the side benefit of making the `saved_value` field unused.
* src/lisp.h (enum specbind_tag): Remove `saved_value` field.
(rebind_for_thread_switch, unbind_for_thread_switch): Delete decls.
(specpdl_unrewind): Declare function.
* src/eval.c (specpdl_saved_value): Delete function.
(specbind): Delete the code related to `saved_value`, and consolidate
common code between the different branches.
(rebind_for_thread_switch, -unbind_for_thread_switch): Move to `thread.c`.
(specpdl_unrewind): New function, extracted from `backtrace_eval_unrewind`.
Use `SET_INTERNAL_THREAD_SWITCH`. Skip the buffer & excursion unwinds
depending on new arg `vars_only`.
(backtrace_eval_unrewind): Use it.
(mark_specpdl): Don't mark `saved_value`.
* src/thread.c (rebind_for_thread_switch, unbind_for_thread_switch):
Move from `eval.c` and rewrite using `specpdl_unrewind`.
* test/src/thread-tests.el (threads-test-bug48990): New test.
* test/Makefile.in (test_template): Add a + as suggested by make:
"warning: jobserver unavailable: using -j1. Add '+' to parent make rule".
Diffstat (limited to 'test/src')
| -rw-r--r-- | test/src/thread-tests.el | 25 |
1 files changed, 25 insertions, 0 deletions
diff --git a/test/src/thread-tests.el b/test/src/thread-tests.el index b7ab31120aa..75d67140a90 100644 --- a/test/src/thread-tests.el +++ b/test/src/thread-tests.el | |||
| @@ -393,4 +393,29 @@ | |||
| 393 | (let ((th (make-thread 'ignore))) | 393 | (let ((th (make-thread 'ignore))) |
| 394 | (should-not (equal th main-thread)))) | 394 | (should-not (equal th main-thread)))) |
| 395 | 395 | ||
| 396 | (defvar threads-test--var 'global) | ||
| 397 | |||
| 398 | (ert-deftest threads-test-bug48990 () | ||
| 399 | (skip-unless (fboundp 'make-thread)) | ||
| 400 | (let ((buf1 (generate-new-buffer " thread-test")) | ||
| 401 | (buf2 (generate-new-buffer " thread-test"))) | ||
| 402 | (with-current-buffer buf1 | ||
| 403 | (setq-local threads-test--var 'local1)) | ||
| 404 | (with-current-buffer buf2 | ||
| 405 | (setq-local threads-test--var 'local2)) | ||
| 406 | (let ((seen nil)) | ||
| 407 | (with-current-buffer buf1 | ||
| 408 | (should (eq threads-test--var 'local1)) | ||
| 409 | (make-thread (lambda () (setq seen threads-test--var)))) | ||
| 410 | (with-current-buffer buf2 | ||
| 411 | (should (eq threads-test--var 'local2)) | ||
| 412 | (let ((threads-test--var 'let2)) | ||
| 413 | (should (eq threads-test--var 'let2)) | ||
| 414 | (while (not seen) | ||
| 415 | (thread-yield)) | ||
| 416 | (should (eq threads-test--var 'let2)) | ||
| 417 | (should (eq seen 'local1))) | ||
| 418 | (should (eq threads-test--var 'local2))) | ||
| 419 | (should (eq threads-test--var 'global))))) | ||
| 420 | |||
| 396 | ;;; thread-tests.el ends here | 421 | ;;; thread-tests.el ends here |