unofficial mirror of emacs-devel@gnu.org 
 help / color / mirror / code / Atom feed
From: Michael Albinus <michael.albinus@gmx.de>
To: Tom Tromey <tom@tromey.com>
Cc: emacs-devel@gnu.org
Subject: Re: Return value of finished threads
Date: Sat, 21 Jul 2018 11:39:17 +0200	[thread overview]
Message-ID: <87wotphqre.fsf@gmx.de> (raw)
In-Reply-To: <87h8kt3hcj.fsf@tromey.com> (Tom Tromey's message of "Fri, 20 Jul 2018 12:14:04 -0600")

[-- Attachment #1: Type: text/plain, Size: 1300 bytes --]

Tom Tromey <tom@tromey.com> writes:

Hi Tom,

> Michael> So I'm wondering if we could extend thread support by an
> Michael> indication of the thread result, when finished. One idea
> Michael> would be that `thread-join' returns with that value.
>
> This doesn't seem all that hard to implement.

Yep. The appended patch does it for me. Maybe you could check whether
I'm missing something?

> Also if the thread exited due to an exception of some kind, this could
> be propagated by thread-join as well.

Yeah, this would be a bonus. I've failed to implement it, so I let it to
somebody else. I don't need it first-hand.

> Michael> The documentation recommends the use of global variables,
> Michael> which would be inconvenient for many threads to supervise.
>
> Or you can use a queue of some kind and have each worker push its
> result there.

Yes, but you must indicate the worker threads where to push the
result. Imagine find-file would support threads for wildcard file names,
and somebody calls find-file this way twice, both running concurrently.
Every worker thread must know, whether to push the result into the
global variable associated with the first call or the second one. Still
overhead to implement; I'll prefer that thread-join returns the result.

> Tom

Best regards, Michael.


[-- Attachment #2: Type: text/plain, Size: 3286 bytes --]

diff --git a/src/thread.c b/src/thread.c
index 754d286e9f..e2d16df7cb 100644
--- a/src/thread.c
+++ b/src/thread.c
@@ -681,7 +681,7 @@ invoke_thread_function (void)
 {
   ptrdiff_t count = SPECPDL_INDEX ();
 
-  Ffuncall (1, &current_thread->function);
+  current_thread->result = Ffuncall (1, &current_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,9 +934,9 @@ 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;
@@ -949,7 +950,7 @@ It is an error for a thread to try to join itself.  */)
   if (thread_alive_p (tstate))
     flush_stack_call_func (thread_join_callback, tstate);
 
-  return Qnil;
+  return tstate->result;
 }
 
 DEFUN ("all-threads", Fall_threads, Sall_threads, 0, 0, 0,
@@ -1017,6 +1018,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 +1092,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 c10e5ecb75..922eea6217 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;
diff --git a/test/src/thread-tests.el b/test/src/thread-tests.el
index a447fb3914..ddf9e987cc 100644
--- a/test/src/thread-tests.el
+++ b/test/src/thread-tests.el
@@ -100,9 +100,9 @@ threads-test-thread1
    (progn
      (setq threads-test-global nil)
      (let ((thread (make-thread #'threads-test-thread1)))
-       (thread-join thread)
-       (and threads-test-global
-	    (not (thread-alive-p thread)))))))
+       (and (= (thread-join thread) 23)
+            (= threads-test-global 23)
+            (not (thread-alive-p thread)))))))
 
 (ert-deftest threads-join-self ()
   "Cannot `thread-join' the current thread."

  reply	other threads:[~2018-07-21  9:39 UTC|newest]

Thread overview: 21+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-07-20 14:56 Return value of finished threads Michael Albinus
2018-07-20 15:08 ` Eli Zaretskii
2018-07-20 15:15   ` Michael Albinus
2018-07-20 16:17     ` Clément Pit-Claudel
2018-07-20 17:25       ` Eli Zaretskii
2018-07-20 16:17 ` Noam Postavsky
2018-07-20 17:31   ` Eli Zaretskii
2018-07-21  9:28     ` Michael Albinus
2018-07-20 18:14 ` Tom Tromey
2018-07-21  9:39   ` Michael Albinus [this message]
2018-07-21 13:07     ` Tom Tromey
2018-07-21 13:16       ` Michael Albinus
2018-07-21 14:19         ` Tom Tromey
2018-07-21 14:33           ` Michael Albinus
2018-07-21 18:16             ` Tom Tromey
2018-07-21 19:33               ` Michael Albinus
2018-07-21 21:39                 ` Tom Tromey
2018-07-22 10:02                   ` Michael Albinus
2018-07-21 22:49         ` Brett Gilio
2018-07-22  2:18           ` Tom Tromey
2018-07-23 18:02             ` Brett Gilio

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

  List information: https://www.gnu.org/software/emacs/

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=87wotphqre.fsf@gmx.de \
    --to=michael.albinus@gmx.de \
    --cc=emacs-devel@gnu.org \
    --cc=tom@tromey.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this public inbox

	https://git.savannah.gnu.org/cgit/emacs.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).