diff options
| author | Michael Albinus | 2018-07-22 11:53:24 +0200 |
|---|---|---|
| committer | Michael Albinus | 2018-07-22 11:53:24 +0200 |
| commit | e23727978dbb07d68f730ffa60b22d59d065850e (patch) | |
| tree | 7ed37a1f0078ba6032a7d924f218c764330a98c8 /src/thread.c | |
| parent | b7ca3d5d932bad6900296679ab87f7d0d64d1de9 (diff) | |
| download | emacs-e23727978dbb07d68f730ffa60b22d59d065850e.tar.gz emacs-e23727978dbb07d68f730ffa60b22d59d065850e.zip | |
thread-join returns the result of finished thread
* doc/lispref/threads.texi (Basic Thread Functions):
* etc/NEWS: Document return value of `thread-join'.
* src/thread.c (invoke_thread_function, Fmake_thread)
(init_main_thread): Set result.
(Fthread_join): Propagate signals, and return result.
(Vmain_thread): New defvar.
* src/thread.h (struct thread_state): Add `result' field.
* test/src/thread-tests.el (threads-join): Test also return value.
(threads-join-error): New test.
(threads-mutex-signal): Check for propagation of `quit' signal.
Diffstat (limited to 'src/thread.c')
| -rw-r--r-- | src/thread.c | 22 |
1 files changed, 15 insertions, 7 deletions
diff --git a/src/thread.c b/src/thread.c index 754d286e9f8..1c73d938655 100644 --- a/src/thread.c +++ b/src/thread.c | |||
| @@ -681,7 +681,7 @@ invoke_thread_function (void) | |||
| 681 | { | 681 | { |
| 682 | ptrdiff_t count = SPECPDL_INDEX (); | 682 | ptrdiff_t count = SPECPDL_INDEX (); |
| 683 | 683 | ||
| 684 | Ffuncall (1, ¤t_thread->function); | 684 | current_thread->result = Ffuncall (1, ¤t_thread->function); |
| 685 | return unbind_to (count, Qnil); | 685 | return unbind_to (count, Qnil); |
| 686 | } | 686 | } |
| 687 | 687 | ||
| @@ -789,6 +789,7 @@ If NAME is given, it must be a string; it names the new thread. */) | |||
| 789 | new_thread->m_last_thing_searched = Qnil; /* copy from parent? */ | 789 | new_thread->m_last_thing_searched = Qnil; /* copy from parent? */ |
| 790 | new_thread->m_saved_last_thing_searched = Qnil; | 790 | new_thread->m_saved_last_thing_searched = Qnil; |
| 791 | new_thread->m_current_buffer = current_thread->m_current_buffer; | 791 | new_thread->m_current_buffer = current_thread->m_current_buffer; |
| 792 | new_thread->result = Qnil; | ||
| 792 | new_thread->error_symbol = Qnil; | 793 | new_thread->error_symbol = Qnil; |
| 793 | new_thread->error_data = Qnil; | 794 | new_thread->error_data = Qnil; |
| 794 | new_thread->event_object = Qnil; | 795 | new_thread->event_object = Qnil; |
| @@ -933,12 +934,13 @@ thread_join_callback (void *arg) | |||
| 933 | 934 | ||
| 934 | DEFUN ("thread-join", Fthread_join, Sthread_join, 1, 1, 0, | 935 | DEFUN ("thread-join", Fthread_join, Sthread_join, 1, 1, 0, |
| 935 | doc: /* Wait for THREAD to exit. | 936 | doc: /* Wait for THREAD to exit. |
| 936 | This blocks the current thread until THREAD exits or until | 937 | This blocks the current thread until THREAD exits or until the current |
| 937 | the current thread is signaled. | 938 | thread is signaled. It returns the result of the THREAD function. It |
| 938 | It is an error for a thread to try to join itself. */) | 939 | is an error for a thread to try to join itself. */) |
| 939 | (Lisp_Object thread) | 940 | (Lisp_Object thread) |
| 940 | { | 941 | { |
| 941 | struct thread_state *tstate; | 942 | struct thread_state *tstate; |
| 943 | Lisp_Object error_symbol, error_data; | ||
| 942 | 944 | ||
| 943 | CHECK_THREAD (thread); | 945 | CHECK_THREAD (thread); |
| 944 | tstate = XTHREAD (thread); | 946 | tstate = XTHREAD (thread); |
| @@ -946,10 +948,16 @@ It is an error for a thread to try to join itself. */) | |||
| 946 | if (tstate == current_thread) | 948 | if (tstate == current_thread) |
| 947 | error ("Cannot join current thread"); | 949 | error ("Cannot join current thread"); |
| 948 | 950 | ||
| 951 | error_symbol = tstate->error_symbol; | ||
| 952 | error_data = tstate->error_data; | ||
| 953 | |||
| 949 | if (thread_alive_p (tstate)) | 954 | if (thread_alive_p (tstate)) |
| 950 | flush_stack_call_func (thread_join_callback, tstate); | 955 | flush_stack_call_func (thread_join_callback, tstate); |
| 951 | 956 | ||
| 952 | return Qnil; | 957 | if (!NILP (error_symbol)) |
| 958 | Fsignal (error_symbol, error_data); | ||
| 959 | |||
| 960 | return tstate->result; | ||
| 953 | } | 961 | } |
| 954 | 962 | ||
| 955 | DEFUN ("all-threads", Fall_threads, Sall_threads, 0, 0, 0, | 963 | DEFUN ("all-threads", Fall_threads, Sall_threads, 0, 0, 0, |
| @@ -1017,6 +1025,7 @@ init_main_thread (void) | |||
| 1017 | main_thread.m_saved_last_thing_searched = Qnil; | 1025 | main_thread.m_saved_last_thing_searched = Qnil; |
| 1018 | main_thread.name = Qnil; | 1026 | main_thread.name = Qnil; |
| 1019 | main_thread.function = Qnil; | 1027 | main_thread.function = Qnil; |
| 1028 | main_thread.result = Qnil; | ||
| 1020 | main_thread.error_symbol = Qnil; | 1029 | main_thread.error_symbol = Qnil; |
| 1021 | main_thread.error_data = Qnil; | 1030 | main_thread.error_data = Qnil; |
| 1022 | main_thread.event_object = Qnil; | 1031 | main_thread.event_object = Qnil; |
| @@ -1090,8 +1099,7 @@ syms_of_threads (void) | |||
| 1090 | DEFSYM (Qmutexp, "mutexp"); | 1099 | DEFSYM (Qmutexp, "mutexp"); |
| 1091 | DEFSYM (Qcondition_variable_p, "condition-variable-p"); | 1100 | DEFSYM (Qcondition_variable_p, "condition-variable-p"); |
| 1092 | 1101 | ||
| 1093 | DEFVAR_LISP ("main-thread", | 1102 | DEFVAR_LISP ("main-thread", Vmain_thread, |
| 1094 | Vmain_thread, | ||
| 1095 | doc: /* The main thread of Emacs. */); | 1103 | doc: /* The main thread of Emacs. */); |
| 1096 | #ifdef THREADS_ENABLED | 1104 | #ifdef THREADS_ENABLED |
| 1097 | XSETTHREAD (Vmain_thread, &main_thread); | 1105 | XSETTHREAD (Vmain_thread, &main_thread); |