summaryrefslogtreecommitdiff
path: root/src/keyboard.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/keyboard.c')
-rw-r--r--src/keyboard.c39
1 files changed, 38 insertions, 1 deletions
diff --git a/src/keyboard.c b/src/keyboard.c
index 4a5eb493b58..3cfc1652084 100644
--- a/src/keyboard.c
+++ b/src/keyboard.c
@@ -45,6 +45,9 @@ Boston, MA 02111-1307, USA. */
#include <setjmp.h>
#include <errno.h>
+#ifdef HAVE_GTK_AND_PTHREAD
+#include <pthread.h>
+#endif
#ifdef MSDOS
#include "msdos.h"
#include <time.h>
@@ -6777,6 +6780,25 @@ handle_async_input ()
#ifdef BSD4_1
extern int select_alarmed;
#endif
+#ifdef HAVE_GTK_AND_PTHREAD
+ extern pthread_t main_thread;
+ if (pthread_self () != main_thread)
+ {
+ /* POSIX says any thread can receive the signal. On GNU/Linux that is
+ not true, but for other systems (FreeBSD at least) it is. So direct
+ the signal to the correct thread and block it from this thread. */
+#ifdef SIGIO
+ sigset_t new_mask;
+
+ sigemptyset (&new_mask);
+ sigaddset (&new_mask, SIGIO);
+ pthread_sigmask (SIG_BLOCK, &new_mask, 0);
+ pthread_kill (main_thread, SIGIO);
+#endif
+ return;
+ }
+#endif
+
interrupt_input_pending = 0;
while (1)
@@ -6804,7 +6826,22 @@ input_available_signal (signo)
{
/* Must preserve main program's value of errno. */
int old_errno = errno;
-
+#ifdef HAVE_GTK_AND_PTHREAD
+ extern pthread_t main_thread;
+ if (pthread_self () != main_thread)
+ {
+ /* POSIX says any thread can receive the signal. On GNU/Linux that is
+ not true, but for other systems (FreeBSD at least) it is. So direct
+ the signal to the correct thread and block it from this thread. */
+ sigset_t new_mask;
+
+ sigemptyset (&new_mask);
+ sigaddset (&new_mask, SIGIO);
+ pthread_sigmask (SIG_BLOCK, &new_mask, 0);
+ pthread_kill (main_thread, SIGIO);
+ return;
+ }
+#endif /* HAVE_GTK_AND_PTHREAD */
#if defined (USG) && !defined (POSIX_SIGNALS)
/* USG systems forget handlers when they are used;
must reestablish each time */