diff options
Diffstat (limited to 'src/thread.c')
| -rw-r--r-- | src/thread.c | 43 |
1 files changed, 34 insertions, 9 deletions
diff --git a/src/thread.c b/src/thread.c index f11e3e5addb..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, |
| @@ -973,11 +981,17 @@ DEFUN ("all-threads", Fall_threads, Sall_threads, 0, 0, 0, | |||
| 973 | return result; | 981 | return result; |
| 974 | } | 982 | } |
| 975 | 983 | ||
| 976 | DEFUN ("thread-last-error", Fthread_last_error, Sthread_last_error, 0, 0, 0, | 984 | DEFUN ("thread-last-error", Fthread_last_error, Sthread_last_error, 0, 1, 0, |
| 977 | doc: /* Return the last error form recorded by a dying thread. */) | 985 | doc: /* Return the last error form recorded by a dying thread. |
| 978 | (void) | 986 | If CLEANUP is non-nil, remove this error form from history. */) |
| 987 | (Lisp_Object cleanup) | ||
| 979 | { | 988 | { |
| 980 | return last_thread_error; | 989 | Lisp_Object result = last_thread_error; |
| 990 | |||
| 991 | if (!NILP (cleanup)) | ||
| 992 | last_thread_error = Qnil; | ||
| 993 | |||
| 994 | return result; | ||
| 981 | } | 995 | } |
| 982 | 996 | ||
| 983 | 997 | ||
| @@ -1011,6 +1025,7 @@ init_main_thread (void) | |||
| 1011 | main_thread.m_saved_last_thing_searched = Qnil; | 1025 | main_thread.m_saved_last_thing_searched = Qnil; |
| 1012 | main_thread.name = Qnil; | 1026 | main_thread.name = Qnil; |
| 1013 | main_thread.function = Qnil; | 1027 | main_thread.function = Qnil; |
| 1028 | main_thread.result = Qnil; | ||
| 1014 | main_thread.error_symbol = Qnil; | 1029 | main_thread.error_symbol = Qnil; |
| 1015 | main_thread.error_data = Qnil; | 1030 | main_thread.error_data = Qnil; |
| 1016 | main_thread.event_object = Qnil; | 1031 | main_thread.event_object = Qnil; |
| @@ -1076,9 +1091,19 @@ syms_of_threads (void) | |||
| 1076 | 1091 | ||
| 1077 | staticpro (&last_thread_error); | 1092 | staticpro (&last_thread_error); |
| 1078 | last_thread_error = Qnil; | 1093 | last_thread_error = Qnil; |
| 1094 | |||
| 1095 | Fprovide (intern_c_string ("threads"), Qnil); | ||
| 1079 | } | 1096 | } |
| 1080 | 1097 | ||
| 1081 | DEFSYM (Qthreadp, "threadp"); | 1098 | DEFSYM (Qthreadp, "threadp"); |
| 1082 | DEFSYM (Qmutexp, "mutexp"); | 1099 | DEFSYM (Qmutexp, "mutexp"); |
| 1083 | DEFSYM (Qcondition_variable_p, "condition-variable-p"); | 1100 | DEFSYM (Qcondition_variable_p, "condition-variable-p"); |
| 1101 | |||
| 1102 | DEFVAR_LISP ("main-thread", Vmain_thread, | ||
| 1103 | doc: /* The main thread of Emacs. */); | ||
| 1104 | #ifdef THREADS_ENABLED | ||
| 1105 | XSETTHREAD (Vmain_thread, &main_thread); | ||
| 1106 | #else | ||
| 1107 | Vmain_thread = Qnil; | ||
| 1108 | #endif | ||
| 1084 | } | 1109 | } |