diff options
| -rw-r--r-- | doc/lispref/threads.texi | 2 | ||||
| -rw-r--r-- | doc/misc/rcirc.texi | 60 | ||||
| -rw-r--r-- | etc/NEWS.26 | 5 | ||||
| -rw-r--r-- | src/thread.c | 17 | ||||
| -rw-r--r-- | test/lisp/calc/calc-tests.el | 7 | ||||
| -rw-r--r-- | test/src/thread-tests.el | 16 |
6 files changed, 48 insertions, 59 deletions
diff --git a/doc/lispref/threads.texi b/doc/lispref/threads.texi index 98301984114..9cdeb798c1d 100644 --- a/doc/lispref/threads.texi +++ b/doc/lispref/threads.texi | |||
| @@ -100,7 +100,7 @@ Yield execution to the next runnable thread. | |||
| 100 | Return the name of @var{thread}, as specified to @code{make-thread}. | 100 | Return the name of @var{thread}, as specified to @code{make-thread}. |
| 101 | @end defun | 101 | @end defun |
| 102 | 102 | ||
| 103 | @defun thread-alive-p thread | 103 | @defun thread-live-p thread |
| 104 | Return @code{t} if @var{thread} is alive, or @code{nil} if it is not. | 104 | Return @code{t} if @var{thread} is alive, or @code{nil} if it is not. |
| 105 | A thread is alive as long as its function is still executing. | 105 | A thread is alive as long as its function is still executing. |
| 106 | @end defun | 106 | @end defun |
diff --git a/doc/misc/rcirc.texi b/doc/misc/rcirc.texi index 2437e020eee..0287054b1d2 100644 --- a/doc/misc/rcirc.texi +++ b/doc/misc/rcirc.texi | |||
| @@ -88,7 +88,6 @@ Hacking and Tweaking | |||
| 88 | * Scrolling conservatively:: | 88 | * Scrolling conservatively:: |
| 89 | * Changing the time stamp format:: | 89 | * Changing the time stamp format:: |
| 90 | * Defining a new command:: | 90 | * Defining a new command:: |
| 91 | * Reconnecting after you have lost the connection:: | ||
| 92 | 91 | ||
| 93 | @end detailmenu | 92 | @end detailmenu |
| 94 | @end menu | 93 | @end menu |
| @@ -401,6 +400,23 @@ This disconnects from the server and parts all channels. You can | |||
| 401 | optionally provide a reason for quitting. When you kill the server | 400 | optionally provide a reason for quitting. When you kill the server |
| 402 | buffer, you automatically quit the server and part all channels. (Also | 401 | buffer, you automatically quit the server and part all channels. (Also |
| 403 | @code{/quit ZZZzzz...}.) | 402 | @code{/quit ZZZzzz...}.) |
| 403 | |||
| 404 | @item /reconnect | ||
| 405 | @cindex /reconnect | ||
| 406 | @cindex reconnect | ||
| 407 | @cindex lost connection | ||
| 408 | @cindex disconnecting servers, reconnecting | ||
| 409 | This reconnects after you have lost the connection. | ||
| 410 | |||
| 411 | If you're chatting from a laptop, then you might be familiar with this | ||
| 412 | problem: When your laptop falls asleep and wakes up later, your IRC | ||
| 413 | client doesn't realize that it has been disconnected. It takes several | ||
| 414 | minutes until the client decides that the connection has in fact been | ||
| 415 | lost. The simple solution is to use @kbd{M-x rcirc}. The problem is | ||
| 416 | that this opens an @emph{additional} connection, so you'll have two | ||
| 417 | copies of every channel buffer, one dead and one live. | ||
| 418 | |||
| 419 | The real answer, therefore, is the @code{/reconnect} command. | ||
| 404 | @end table | 420 | @end table |
| 405 | 421 | ||
| 406 | @node Useful IRC commands | 422 | @node Useful IRC commands |
| @@ -787,7 +803,6 @@ Here are some examples of stuff you can do to configure @code{rcirc}. | |||
| 787 | * Scrolling conservatively:: | 803 | * Scrolling conservatively:: |
| 788 | * Changing the time stamp format:: | 804 | * Changing the time stamp format:: |
| 789 | * Defining a new command:: | 805 | * Defining a new command:: |
| 790 | * Reconnecting after you have lost the connection:: | ||
| 791 | @end menu | 806 | @end menu |
| 792 | 807 | ||
| 793 | @node Skipping /away messages using handlers | 808 | @node Skipping /away messages using handlers |
| @@ -888,47 +903,6 @@ because @code{defun-rcirc-command} is not yet available, and without | |||
| 888 | (concat "I use " rcirc-id-string)))) | 903 | (concat "I use " rcirc-id-string)))) |
| 889 | @end smallexample | 904 | @end smallexample |
| 890 | 905 | ||
| 891 | @node Reconnecting after you have lost the connection | ||
| 892 | @section Reconnecting after you have lost the connection | ||
| 893 | @cindex reconnecting | ||
| 894 | @cindex disconnecting servers, reconnecting | ||
| 895 | |||
| 896 | If you're chatting from a laptop, then you might be familiar with this | ||
| 897 | problem: When your laptop falls asleep and wakes up later, your IRC | ||
| 898 | client doesn't realize that it has been disconnected. It takes several | ||
| 899 | minutes until the client decides that the connection has in fact been | ||
| 900 | lost. The simple solution is to use @kbd{M-x rcirc}. The problem is | ||
| 901 | that this opens an @emph{additional} connection, so you'll have two | ||
| 902 | copies of every channel buffer, one dead and one live. | ||
| 903 | |||
| 904 | The real answer, therefore, is a @code{/reconnect} command: | ||
| 905 | |||
| 906 | @smallexample | ||
| 907 | (with-eval-after-load 'rcirc | ||
| 908 | (defun-rcirc-command reconnect (arg) | ||
| 909 | "Reconnect the server process." | ||
| 910 | (interactive "i") | ||
| 911 | (unless process | ||
| 912 | (error "There's no process for this target")) | ||
| 913 | (let* ((server (car (process-contact process))) | ||
| 914 | (port (process-contact process :service)) | ||
| 915 | (nick (rcirc-nick process)) | ||
| 916 | channels query-buffers) | ||
| 917 | (dolist (buf (buffer-list)) | ||
| 918 | (with-current-buffer buf | ||
| 919 | (when (eq process (rcirc-buffer-process)) | ||
| 920 | (remove-hook 'change-major-mode-hook | ||
| 921 | 'rcirc-change-major-mode-hook) | ||
| 922 | (if (rcirc-channel-p rcirc-target) | ||
| 923 | (setq channels (cons rcirc-target channels)) | ||
| 924 | (setq query-buffers (cons buf query-buffers)))))) | ||
| 925 | (delete-process process) | ||
| 926 | (rcirc-connect server port nick | ||
| 927 | rcirc-default-user-name | ||
| 928 | rcirc-default-full-name | ||
| 929 | channels)))) | ||
| 930 | @end smallexample | ||
| 931 | |||
| 932 | @node GNU Free Documentation License | 906 | @node GNU Free Documentation License |
| 933 | @appendix GNU Free Documentation License | 907 | @appendix GNU Free Documentation License |
| 934 | @include doclicense.texi | 908 | @include doclicense.texi |
diff --git a/etc/NEWS.26 b/etc/NEWS.26 index e94bda549ab..97222705e61 100644 --- a/etc/NEWS.26 +++ b/etc/NEWS.26 | |||
| @@ -99,6 +99,11 @@ option 'vc-hg-symbolic-revision-styles' to the value '("{rev}")'. | |||
| 99 | Existing files "~/.emacs.d/shadows" and "~/.emacs.d/shadow_todo" must | 99 | Existing files "~/.emacs.d/shadows" and "~/.emacs.d/shadow_todo" must |
| 100 | be removed prior using the changed 'shadow-*' commands. | 100 | be removed prior using the changed 'shadow-*' commands. |
| 101 | 101 | ||
| 102 | +++ | ||
| 103 | ** 'thread-alive-p' has been renamed to 'thread-live-p'. | ||
| 104 | The old name is an alias of the new name. Future Emacs version will | ||
| 105 | obsolete it. | ||
| 106 | |||
| 102 | 107 | ||
| 103 | * Lisp Changes in Emacs 26.2 | 108 | * Lisp Changes in Emacs 26.2 |
| 104 | 109 | ||
diff --git a/src/thread.c b/src/thread.c index 081569f8a38..fc933440fcc 100644 --- a/src/thread.c +++ b/src/thread.c | |||
| @@ -41,7 +41,7 @@ extern volatile int interrupt_input_blocked; | |||
| 41 | 41 | ||
| 42 | /* m_specpdl is set when the thread is created and cleared when the | 42 | /* m_specpdl is set when the thread is created and cleared when the |
| 43 | thread dies. */ | 43 | thread dies. */ |
| 44 | #define thread_alive_p(STATE) ((STATE)->m_specpdl != NULL) | 44 | #define thread_live_p(STATE) ((STATE)->m_specpdl != NULL) |
| 45 | 45 | ||
| 46 | 46 | ||
| 47 | 47 | ||
| @@ -904,7 +904,7 @@ If THREAD is the main thread, just the error message is shown. */) | |||
| 904 | return Qnil; | 904 | return Qnil; |
| 905 | } | 905 | } |
| 906 | 906 | ||
| 907 | DEFUN ("thread-alive-p", Fthread_alive_p, Sthread_alive_p, 1, 1, 0, | 907 | DEFUN ("thread-live-p", Fthread_live_p, Sthread_live_p, 1, 1, 0, |
| 908 | doc: /* Return t if THREAD is alive, or nil if it has exited. */) | 908 | doc: /* Return t if THREAD is alive, or nil if it has exited. */) |
| 909 | (Lisp_Object thread) | 909 | (Lisp_Object thread) |
| 910 | { | 910 | { |
| @@ -913,7 +913,7 @@ DEFUN ("thread-alive-p", Fthread_alive_p, Sthread_alive_p, 1, 1, 0, | |||
| 913 | CHECK_THREAD (thread); | 913 | CHECK_THREAD (thread); |
| 914 | tstate = XTHREAD (thread); | 914 | tstate = XTHREAD (thread); |
| 915 | 915 | ||
| 916 | return thread_alive_p (tstate) ? Qt : Qnil; | 916 | return thread_live_p (tstate) ? Qt : Qnil; |
| 917 | } | 917 | } |
| 918 | 918 | ||
| 919 | DEFUN ("thread--blocker", Fthread_blocker, Sthread_blocker, 1, 1, 0, | 919 | DEFUN ("thread--blocker", Fthread_blocker, Sthread_blocker, 1, 1, 0, |
| @@ -943,7 +943,7 @@ thread_join_callback (void *arg) | |||
| 943 | XSETTHREAD (thread, tstate); | 943 | XSETTHREAD (thread, tstate); |
| 944 | self->event_object = thread; | 944 | self->event_object = thread; |
| 945 | self->wait_condvar = &tstate->thread_condvar; | 945 | self->wait_condvar = &tstate->thread_condvar; |
| 946 | while (thread_alive_p (tstate) && NILP (self->error_symbol)) | 946 | while (thread_live_p (tstate) && NILP (self->error_symbol)) |
| 947 | sys_cond_wait (self->wait_condvar, &global_lock); | 947 | sys_cond_wait (self->wait_condvar, &global_lock); |
| 948 | 948 | ||
| 949 | self->wait_condvar = NULL; | 949 | self->wait_condvar = NULL; |
| @@ -970,7 +970,7 @@ is an error for a thread to try to join itself. */) | |||
| 970 | error_symbol = tstate->error_symbol; | 970 | error_symbol = tstate->error_symbol; |
| 971 | error_data = tstate->error_data; | 971 | error_data = tstate->error_data; |
| 972 | 972 | ||
| 973 | if (thread_alive_p (tstate)) | 973 | if (thread_live_p (tstate)) |
| 974 | flush_stack_call_func (thread_join_callback, tstate); | 974 | flush_stack_call_func (thread_join_callback, tstate); |
| 975 | 975 | ||
| 976 | if (!NILP (error_symbol)) | 976 | if (!NILP (error_symbol)) |
| @@ -988,7 +988,7 @@ DEFUN ("all-threads", Fall_threads, Sall_threads, 0, 0, 0, | |||
| 988 | 988 | ||
| 989 | for (iter = all_threads; iter; iter = iter->next_thread) | 989 | for (iter = all_threads; iter; iter = iter->next_thread) |
| 990 | { | 990 | { |
| 991 | if (thread_alive_p (iter)) | 991 | if (thread_live_p (iter)) |
| 992 | { | 992 | { |
| 993 | Lisp_Object thread; | 993 | Lisp_Object thread; |
| 994 | 994 | ||
| @@ -1093,7 +1093,7 @@ syms_of_threads (void) | |||
| 1093 | defsubr (&Scurrent_thread); | 1093 | defsubr (&Scurrent_thread); |
| 1094 | defsubr (&Sthread_name); | 1094 | defsubr (&Sthread_name); |
| 1095 | defsubr (&Sthread_signal); | 1095 | defsubr (&Sthread_signal); |
| 1096 | defsubr (&Sthread_alive_p); | 1096 | defsubr (&Sthread_live_p); |
| 1097 | defsubr (&Sthread_join); | 1097 | defsubr (&Sthread_join); |
| 1098 | defsubr (&Sthread_blocker); | 1098 | defsubr (&Sthread_blocker); |
| 1099 | defsubr (&Sall_threads); | 1099 | defsubr (&Sall_threads); |
| @@ -1111,6 +1111,9 @@ syms_of_threads (void) | |||
| 1111 | staticpro (&last_thread_error); | 1111 | staticpro (&last_thread_error); |
| 1112 | last_thread_error = Qnil; | 1112 | last_thread_error = Qnil; |
| 1113 | 1113 | ||
| 1114 | Fdefalias (intern_c_string ("thread-alive-p"), | ||
| 1115 | intern_c_string ("thread-live-p"), Qnil); | ||
| 1116 | |||
| 1114 | Fprovide (intern_c_string ("threads"), Qnil); | 1117 | Fprovide (intern_c_string ("threads"), Qnil); |
| 1115 | } | 1118 | } |
| 1116 | 1119 | ||
diff --git a/test/lisp/calc/calc-tests.el b/test/lisp/calc/calc-tests.el index fbd5f0e3a1d..101786c30e3 100644 --- a/test/lisp/calc/calc-tests.el +++ b/test/lisp/calc/calc-tests.el | |||
| @@ -86,6 +86,13 @@ An existing calc stack is reused, otherwise a new one is created." | |||
| 86 | (math-read-expr "1m") "cm") | 86 | (math-read-expr "1m") "cm") |
| 87 | '(* -100 (var cm var-cm))))) | 87 | '(* -100 (var cm var-cm))))) |
| 88 | 88 | ||
| 89 | (ert-deftest calc-imaginary-i () | ||
| 90 | "Test `math-imaginary-i' for non-special-const values." | ||
| 91 | (let ((var-i (calcFunc-polar (calcFunc-sqrt -1)))) | ||
| 92 | (should (math-imaginary-i))) | ||
| 93 | (let ((var-i (calcFunc-sqrt -1))) | ||
| 94 | (should (math-imaginary-i)))) | ||
| 95 | |||
| 89 | (ert-deftest test-calc-23889 () | 96 | (ert-deftest test-calc-23889 () |
| 90 | "Test for https://debbugs.gnu.org/23889 and 25652." | 97 | "Test for https://debbugs.gnu.org/23889 and 25652." |
| 91 | (skip-unless (>= math-bignum-digit-length 9)) | 98 | (skip-unless (>= math-bignum-digit-length 9)) |
diff --git a/test/src/thread-tests.el b/test/src/thread-tests.el index cc1dff8a281..a87eb3e1591 100644 --- a/test/src/thread-tests.el +++ b/test/src/thread-tests.el | |||
| @@ -34,7 +34,7 @@ | |||
| 34 | (declare-function mutex-lock "thread.c" (mutex)) | 34 | (declare-function mutex-lock "thread.c" (mutex)) |
| 35 | (declare-function mutex-unlock "thread.c" (mutex)) | 35 | (declare-function mutex-unlock "thread.c" (mutex)) |
| 36 | (declare-function thread--blocker "thread.c" (thread)) | 36 | (declare-function thread--blocker "thread.c" (thread)) |
| 37 | (declare-function thread-alive-p "thread.c" (thread)) | 37 | (declare-function thread-live-p "thread.c" (thread)) |
| 38 | (declare-function thread-join "thread.c" (thread)) | 38 | (declare-function thread-join "thread.c" (thread)) |
| 39 | (declare-function thread-last-error "thread.c" (&optional cleanup)) | 39 | (declare-function thread-last-error "thread.c" (&optional cleanup)) |
| 40 | (declare-function thread-name "thread.c" (thread)) | 40 | (declare-function thread-name "thread.c" (thread)) |
| @@ -63,11 +63,11 @@ | |||
| 63 | (should | 63 | (should |
| 64 | (string= "hi bob" (thread-name (make-thread #'ignore "hi bob"))))) | 64 | (string= "hi bob" (thread-name (make-thread #'ignore "hi bob"))))) |
| 65 | 65 | ||
| 66 | (ert-deftest threads-alive () | 66 | (ert-deftest threads-live () |
| 67 | "Test for thread liveness." | 67 | "Test for thread liveness." |
| 68 | (skip-unless (featurep 'threads)) | 68 | (skip-unless (featurep 'threads)) |
| 69 | (should | 69 | (should |
| 70 | (thread-alive-p (make-thread #'ignore)))) | 70 | (thread-live-p (make-thread #'ignore)))) |
| 71 | 71 | ||
| 72 | (ert-deftest threads-all-threads () | 72 | (ert-deftest threads-all-threads () |
| 73 | "Simple test for all-threads." | 73 | "Simple test for all-threads." |
| @@ -104,7 +104,7 @@ | |||
| 104 | (let ((thread (make-thread #'threads-test-thread1))) | 104 | (let ((thread (make-thread #'threads-test-thread1))) |
| 105 | (and (= (thread-join thread) 23) | 105 | (and (= (thread-join thread) 23) |
| 106 | (= threads-test-global 23) | 106 | (= threads-test-global 23) |
| 107 | (not (thread-alive-p thread))))))) | 107 | (not (thread-live-p thread))))))) |
| 108 | 108 | ||
| 109 | (ert-deftest threads-join-self () | 109 | (ert-deftest threads-join-self () |
| 110 | "Cannot `thread-join' the current thread." | 110 | "Cannot `thread-join' the current thread." |
| @@ -290,7 +290,7 @@ | |||
| 290 | (let (th1 th2) | 290 | (let (th1 th2) |
| 291 | (setq th1 (make-thread #'threads-call-error "call-error")) | 291 | (setq th1 (make-thread #'threads-call-error "call-error")) |
| 292 | (should (threadp th1)) | 292 | (should (threadp th1)) |
| 293 | (while (thread-alive-p th1) | 293 | (while (thread-live-p th1) |
| 294 | (thread-yield)) | 294 | (thread-yield)) |
| 295 | (should (equal (thread-last-error) | 295 | (should (equal (thread-last-error) |
| 296 | '(error "Error is called"))) | 296 | '(error "Error is called"))) |
| @@ -319,7 +319,7 @@ | |||
| 319 | (while t (thread-yield)))))) | 319 | (while t (thread-yield)))))) |
| 320 | (thread-signal thread 'error nil) | 320 | (thread-signal thread 'error nil) |
| 321 | (sit-for 1) | 321 | (sit-for 1) |
| 322 | (should-not (thread-alive-p thread)) | 322 | (should-not (thread-live-p thread)) |
| 323 | (should (equal (thread-last-error) '(error))))) | 323 | (should (equal (thread-last-error) '(error))))) |
| 324 | 324 | ||
| 325 | (ert-deftest threads-signal-main-thread () | 325 | (ert-deftest threads-signal-main-thread () |
| @@ -364,7 +364,7 @@ | |||
| 364 | (setq new-thread (make-thread #'threads-test-condvar-wait)) | 364 | (setq new-thread (make-thread #'threads-test-condvar-wait)) |
| 365 | 365 | ||
| 366 | ;; Make sure new-thread is alive. | 366 | ;; Make sure new-thread is alive. |
| 367 | (should (thread-alive-p new-thread)) | 367 | (should (thread-live-p new-thread)) |
| 368 | (should (= (length (all-threads)) 2)) | 368 | (should (= (length (all-threads)) 2)) |
| 369 | ;; Wait for new-thread to become blocked on the condvar. | 369 | ;; Wait for new-thread to become blocked on the condvar. |
| 370 | (while (not (eq (thread--blocker new-thread) threads-condvar)) | 370 | (while (not (eq (thread--blocker new-thread) threads-condvar)) |
| @@ -377,7 +377,7 @@ | |||
| 377 | (sleep-for 0.1) | 377 | (sleep-for 0.1) |
| 378 | ;; Make sure the thread is still there. This used to fail due to | 378 | ;; Make sure the thread is still there. This used to fail due to |
| 379 | ;; a bug in thread.c:condition_wait_callback. | 379 | ;; a bug in thread.c:condition_wait_callback. |
| 380 | (should (thread-alive-p new-thread)) | 380 | (should (thread-live-p new-thread)) |
| 381 | (should (= (length (all-threads)) 2)) | 381 | (should (= (length (all-threads)) 2)) |
| 382 | (should (eq (thread--blocker new-thread) threads-condvar)) | 382 | (should (eq (thread--blocker new-thread) threads-condvar)) |
| 383 | 383 | ||