diff options
| author | Michael Albinus <michael.albinus@gmx.de> | 2018-07-22 11:53:24 +0200 |
|---|---|---|
| committer | Michael Albinus <michael.albinus@gmx.de> | 2018-07-22 11:53:24 +0200 |
| commit | e23727978dbb07d68f730ffa60b22d59d065850e (patch) | |
| tree | 7ed37a1f0078ba6032a7d924f218c764330a98c8 /src | |
| parent | b7ca3d5d932bad6900296679ab87f7d0d64d1de9 (diff) | |
| download | emacs-e23727978dbb07d68f730ffa60b22d59d065850e.tar.gz | |
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')
| -rw-r--r-- | src/thread.c | 22 | ||||
| -rw-r--r-- | src/thread.h | 3 |
2 files changed, 18 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) { ptrdiff_t count = SPECPDL_INDEX (); - Ffuncall (1, ¤t_thread->function); + current_thread->result = Ffuncall (1, ¤t_thread->function); return unbind_to (count, Qnil); } @@ -789,6 +789,7 @@ If NAME is given, it must be a string; it names the new thread. */) new_thread->m_last_thing_searched = Qnil; /* copy from parent? */ new_thread->m_saved_last_thing_searched = Qnil; new_thread->m_current_buffer = current_thread->m_current_buffer; + new_thread->result = Qnil; new_thread->error_symbol = Qnil; new_thread->error_data = Qnil; new_thread->event_object = Qnil; @@ -933,12 +934,13 @@ thread_join_callback (void *arg) DEFUN ("thread-join", Fthread_join, Sthread_join, 1, 1, 0, doc: /* Wait for THREAD to exit. -This blocks the current thread until THREAD exits or until -the current thread is signaled. -It is an error for a thread to try to join itself. */) +This blocks the current thread until THREAD exits or until the current +thread is signaled. It returns the result of the THREAD function. It +is an error for a thread to try to join itself. */) (Lisp_Object thread) { struct thread_state *tstate; + Lisp_Object error_symbol, error_data; CHECK_THREAD (thread); tstate = XTHREAD (thread); @@ -946,10 +948,16 @@ It is an error for a thread to try to join itself. */) if (tstate == current_thread) error ("Cannot join current thread"); + error_symbol = tstate->error_symbol; + error_data = tstate->error_data; + if (thread_alive_p (tstate)) flush_stack_call_func (thread_join_callback, tstate); - return Qnil; + if (!NILP (error_symbol)) + Fsignal (error_symbol, error_data); + + return tstate->result; } DEFUN ("all-threads", Fall_threads, Sall_threads, 0, 0, 0, @@ -1017,6 +1025,7 @@ init_main_thread (void) main_thread.m_saved_last_thing_searched = Qnil; main_thread.name = Qnil; main_thread.function = Qnil; + main_thread.result = Qnil; main_thread.error_symbol = Qnil; main_thread.error_data = Qnil; main_thread.event_object = Qnil; @@ -1090,8 +1099,7 @@ syms_of_threads (void) DEFSYM (Qmutexp, "mutexp"); DEFSYM (Qcondition_variable_p, "condition-variable-p"); - DEFVAR_LISP ("main-thread", - Vmain_thread, + DEFVAR_LISP ("main-thread", Vmain_thread, doc: /* The main thread of Emacs. */); #ifdef THREADS_ENABLED XSETTHREAD (Vmain_thread, &main_thread); diff --git a/src/thread.h b/src/thread.h index c10e5ecb758..922eea62178 100644 --- a/src/thread.h +++ b/src/thread.h @@ -52,6 +52,9 @@ struct thread_state /* The thread's function. */ Lisp_Object function; + /* The thread's result, if function has finished. */ + Lisp_Object result; + /* If non-nil, this thread has been signaled. */ Lisp_Object error_symbol; Lisp_Object error_data; |
