unofficial mirror of emacs-devel@gnu.org 
 help / color / mirror / code / Atom feed
From: Paul Eggert <eggert@cs.ucla.edu>
To: Eli Zaretskii <eliz@gnu.org>
Cc: emacs-devel@gnu.org
Subject: Re: Delivering SIGIO when several threads are active?
Date: Fri, 30 Dec 2016 13:05:44 -0800	[thread overview]
Message-ID: <90c023d2-7e44-d159-9249-0e749c05a584@cs.ucla.edu> (raw)
In-Reply-To: <83wpehs1pm.fsf@gnu.org>

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

Eli Zaretskii wrote:
> what if another thread
> is waiting on the keyboard descriptor and wants to handle keyboard
> input, or wants to receive X events?

That depends on what is meant by "waiting on the keyboard descriptor" and "wants 
to receive X events". At the low level, if the other thread was not involved in 
delivering the signal and is calling pselect on the keyboard descriptor while 
keyboard input occurs, pselect will return successfully without being 
interrupted. Similarly for X events, I assume.

>> On GNU/Linux, process signals get sent to the main thread unless the main thread
>> is blocking them (or if a few less-common situations arise, e.g., the main
>> thread is exiting).
> And what happens in those exceptional cases?

Typically the signal gets sent to some other thread. (There are exceptions to 
this, too; it's complicated.)

>> Hmm, I see that the recent changes use mixed terminology. Until now, Emacs has
>> called the initial thread the "main thread", but the recent code sometimes calls
>> it the "primary thread". We shouldn't have two names for the same thing. I'll
>> look into fixing that.
> "Primary thread" is the name of the main thread.

How so? Threads don't have names in Emacs.

In POSIX it's called the "initial thread". Emacs has long used "main thread" 
internally to describe the same thing; this is a common alternative name, and 
it's shorter so it's OK as long as we're consistent about it. Using a *third* 
phrase "primary thread" for the same thing in some places adds needless confusion.

Evidently the longstanding variable named main_thread (which is a thread ID) got 
in the way of the names that thread.c should have used, and thread.c instead 
used names like "primary_thread". I'll try to lessen the confusion by changing 
the longstanding variable name to "main_thread_id" (which is more-accurate 
anyway). This will give thread.c the freedom to use names like "main_thread" for 
its own purposes. Also, it'll avoid an unnecessary duplicate of the main thread 
ID in emacs-module.c. I installed the attached patch to do all this.

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: 0001-Rename-main_thread-to-main_thread_id-and-simplify.patch --]
[-- Type: text/x-diff; name="0001-Rename-main_thread-to-main_thread_id-and-simplify.patch", Size: 6484 bytes --]

From 01adadb144b7bdd456ceb38076e6add925ba6e24 Mon Sep 17 00:00:00 2001
From: Paul Eggert <eggert@cs.ucla.edu>
Date: Fri, 30 Dec 2016 13:01:39 -0800
Subject: [PATCH] Rename main_thread to main_thread_id and simplify

* src/emacs-module.c: Include syssignal.h, for main_thread_id.
[HAVE_PTHREAD]: Do not include pthread.h.
(main_thread): Remove.  All uses replaced by main_thread_id,
or by dwMainThreadId on NT.  Since the HAVE_PTHREAD code is now using
the main_thread_id established by sysdep.c, there is no need for a
separate copy of the main thread ID here.
(module_init): Remove.  All uses removed.
* src/sysdep.c (main_thread_id) [HAVE_PTHREAD]:
Rename from main_thread.  All uses changed.  Now extern.
---
 src/emacs-module.c | 30 ++++--------------------------
 src/emacs.c        |  6 ------
 src/lisp.h         |  1 -
 src/sysdep.c       | 14 +++++++-------
 src/syssignal.h    |  1 +
 5 files changed, 12 insertions(+), 40 deletions(-)

diff --git a/src/emacs-module.c b/src/emacs-module.c
index 68aeb0c..280c055 100644
--- a/src/emacs-module.c
+++ b/src/emacs-module.c
@@ -28,6 +28,7 @@ along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.  */
 #include "lisp.h"
 #include "dynlib.h"
 #include "coding.h"
+#include "syssignal.h"
 
 #include <intprops.h>
 #include <verify.h>
@@ -41,15 +42,9 @@ enum { module_has_cleanup = true };
 enum { module_has_cleanup = false };
 #endif
 
-/* Handle to the main thread.  Used to verify that modules call us in
-   the right thread.  */
-#ifdef HAVE_PTHREAD
-# include <pthread.h>
-static pthread_t main_thread;
-#elif defined WINDOWSNT
+#ifdef WINDOWSNT
 #include <windows.h>
 #include "w32term.h"
-static DWORD main_thread;
 #endif
 
 /* True if Lisp_Object and emacs_value have the same representation.
@@ -751,9 +746,9 @@ static void
 check_main_thread (void)
 {
 #ifdef HAVE_PTHREAD
-  eassert (pthread_equal (pthread_self (), main_thread));
+  eassert (pthread_equal (pthread_self (), main_thread_id));
 #elif defined WINDOWSNT
-  eassert (GetCurrentThreadId () == main_thread);
+  eassert (GetCurrentThreadId () == dwMainThreadId);
 #endif
 }
 
@@ -1062,20 +1057,3 @@ syms_of_module (void)
   DEFSYM (Qinternal__module_call, "internal--module-call");
   defsubr (&Sinternal_module_call);
 }
-
-/* Unlike syms_of_module, this initializer is called even from an
-   initialized (dumped) Emacs.  */
-
-void
-module_init (void)
-{
-  /* It is not guaranteed that dynamic initializers run in the main thread,
-     therefore detect the main thread here.  */
-#ifdef HAVE_PTHREAD
-  main_thread = pthread_self ();
-#elif defined WINDOWSNT
-  /* The 'main' function already recorded the main thread's thread ID,
-     so we need just to use it . */
-  main_thread = dwMainThreadId;
-#endif
-}
diff --git a/src/emacs.c b/src/emacs.c
index eff3f9d..d461fe2 100644
--- a/src/emacs.c
+++ b/src/emacs.c
@@ -738,8 +738,6 @@ main (int argc, char **argv)
      non-ASCII file names during startup.  */
   w32_init_file_name_codepage ();
 #endif
-  /* This has to be done before module_init is called below, so that
-     the latter could use the thread ID of the main thread.  */
   w32_init_main_thread ();
 #endif
 
@@ -757,10 +755,6 @@ main (int argc, char **argv)
   init_standard_fds ();
   atexit (close_output_streams);
 
-#ifdef HAVE_MODULES
-  module_init ();
-#endif
-
   sort_args (argc, argv);
   argc = 0;
   while (argv[argc]) argc++;
diff --git a/src/lisp.h b/src/lisp.h
index 1a586ca..8496308 100644
--- a/src/lisp.h
+++ b/src/lisp.h
@@ -3880,7 +3880,6 @@ extern bool let_shadows_global_binding_p (Lisp_Object symbol);
 extern Lisp_Object make_user_ptr (void (*finalizer) (void *), void *p);
 
 /* Defined in emacs-module.c.  */
-extern void module_init (void);
 extern void syms_of_module (void);
 #endif
 
diff --git a/src/sysdep.c b/src/sysdep.c
index 1ba336e..1227afc 100644
--- a/src/sysdep.c
+++ b/src/sysdep.c
@@ -1612,7 +1612,7 @@ emacs_sigaction_init (struct sigaction *action, signal_handler_t handler)
 }
 
 #ifdef FORWARD_SIGNAL_TO_MAIN_THREAD
-static pthread_t main_thread;
+pthread_t main_thread_id;
 #endif
 
 /* SIG has arrived at the current process.  Deliver it to the main
@@ -1636,13 +1636,13 @@ deliver_process_signal (int sig, signal_handler_t handler)
 
   bool on_main_thread = true;
 #ifdef FORWARD_SIGNAL_TO_MAIN_THREAD
-  if (! pthread_equal (pthread_self (), main_thread))
+  if (! pthread_equal (pthread_self (), main_thread_id))
     {
       sigset_t blocked;
       sigemptyset (&blocked);
       sigaddset (&blocked, sig);
       pthread_sigmask (SIG_BLOCK, &blocked, 0);
-      pthread_kill (main_thread, sig);
+      pthread_kill (main_thread_id, sig);
       on_main_thread = false;
     }
 #endif
@@ -1668,12 +1668,12 @@ deliver_thread_signal (int sig, signal_handler_t handler)
   int old_errno = errno;
 
 #ifdef FORWARD_SIGNAL_TO_MAIN_THREAD
-  if (! pthread_equal (pthread_self (), main_thread))
+  if (! pthread_equal (pthread_self (), main_thread_id))
     {
       thread_backtrace_npointers
 	= backtrace (thread_backtrace_buffer, BACKTRACE_LIMIT_MAX);
       sigaction (sig, &process_fatal_action, 0);
-      pthread_kill (main_thread, sig);
+      pthread_kill (main_thread_id, sig);
 
       /* Avoid further damage while the main thread is exiting.  */
       while (1)
@@ -1796,7 +1796,7 @@ handle_sigsegv (int sig, siginfo_t *siginfo, void *arg)
   bool fatal = gc_in_progress;
 
 #ifdef FORWARD_SIGNAL_TO_MAIN_THREAD
-  if (!fatal && !pthread_equal (pthread_self (), main_thread))
+  if (!fatal && !pthread_equal (pthread_self (), main_thread_id))
     fatal = true;
 #endif
 
@@ -1888,7 +1888,7 @@ init_signals (bool dumping)
   sigemptyset (&empty_mask);
 
 #ifdef FORWARD_SIGNAL_TO_MAIN_THREAD
-  main_thread = pthread_self ();
+  main_thread_id = pthread_self ();
 #endif
 
 #if !HAVE_DECL_SYS_SIGLIST && !defined _sys_siglist
diff --git a/src/syssignal.h b/src/syssignal.h
index 62704fc..215aafe 100644
--- a/src/syssignal.h
+++ b/src/syssignal.h
@@ -32,6 +32,7 @@ extern void unblock_tty_out_signal (sigset_t const *);
 
 #ifdef HAVE_PTHREAD
 #include <pthread.h>
+extern pthread_t main_thread_id;
 /* If defined, asynchronous signals delivered to a non-main thread are
    forwarded to the main thread.  */
 #define FORWARD_SIGNAL_TO_MAIN_THREAD
-- 
2.7.4


  reply	other threads:[~2016-12-30 21:05 UTC|newest]

Thread overview: 5+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-12-30 10:25 Delivering SIGIO when several threads are active? Eli Zaretskii
2016-12-30 17:54 ` Paul Eggert
2016-12-30 18:37   ` Eli Zaretskii
2016-12-30 21:05     ` Paul Eggert [this message]
2016-12-30 21:45       ` Paul Eggert

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=90c023d2-7e44-d159-9249-0e749c05a584@cs.ucla.edu \
    --to=eggert@cs.ucla.edu \
    --cc=eliz@gnu.org \
    --cc=emacs-devel@gnu.org \
    /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).