emacs-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: usr1-signal, usr2-signal, etc.


From: YAMAMOTO Mitsuharu
Subject: Re: usr1-signal, usr2-signal, etc.
Date: Wed, 13 Dec 2006 18:38:48 +0900
User-agent: Wanderlust/2.14.0 (Africa) SEMI/1.14.6 (Maruoka) FLIM/1.14.8 (Shijō) APEL/10.6 Emacs/22.0.91 (sparc-sun-solaris2.8) MULE/5.0 (SAKAKI)

>>>>> On Tue, 12 Dec 2006 14:54:06 +0100, address@hidden (Kim F. Storm) said:

>>> What if the signal handlers just increment a global counter (one
>>> for each signal type), and the main loop in keyboard.c checked
>>> those counters and added the pending signal events in the "safe
>>> context"?
>> 
>> There're two problems I can think of with this approach.

> You are absolutely right about those problems, but they both existed
> before.  In both cases, they only mean a delay in delivering the
> signal event, which already was a problem in the original code.

I tried minimizing the first problem, but the second one still
remains.

BTW, is it necessary for us to read these events by read-key-sequence?
If not, it looks natural to bind them in special-event-map.

                                     YAMAMOTO Mitsuharu
                                address@hidden

Index: src/emacs.c
===================================================================
RCS file: /cvsroot/emacs/emacs/src/emacs.c,v
retrieving revision 1.394
diff -c -p -r1.394 emacs.c
*** src/emacs.c 8 Dec 2006 00:20:17 -0000       1.394
--- src/emacs.c 13 Dec 2006 09:35:28 -0000
*************** pthread_t main_thread;
*** 361,384 ****
  #endif
  
  
- #if defined (SIGUSR1) || defined (SIGUSR2)
- SIGTYPE
- handle_user_signal (sig)
-      int sig;
- {
-   struct input_event buf;
- 
-   SIGNAL_THREAD_CHECK (sig);
-   bzero (&buf, sizeof buf);
-   buf.kind = USER_SIGNAL_EVENT;
-   buf.frame_or_window = selected_frame;
- 
-   kbd_buffer_store_event (&buf);
-   buf.code = sig;
-   kbd_buffer_store_event (&buf);
- }
- #endif
- 
  /* Handle bus errors, invalid instruction, etc.  */
  SIGTYPE
  fatal_error_signal (sig)
--- 361,366 ----
*************** main (argc, argv
*** 1211,1220 ****
        signal (SIGILL, fatal_error_signal);
        signal (SIGTRAP, fatal_error_signal);
  #ifdef SIGUSR1
!       signal (SIGUSR1, handle_user_signal);
  #endif
  #ifdef SIGUSR2
!       signal (SIGUSR2, handle_user_signal);
  #endif
  #ifdef SIGABRT
        signal (SIGABRT, fatal_error_signal);
--- 1193,1202 ----
        signal (SIGILL, fatal_error_signal);
        signal (SIGTRAP, fatal_error_signal);
  #ifdef SIGUSR1
!       add_user_signal (SIGUSR1, "usr1");
  #endif
  #ifdef SIGUSR2
!       add_user_signal (SIGUSR2, "usr2");
  #endif
  #ifdef SIGABRT
        signal (SIGABRT, fatal_error_signal);
Index: src/keyboard.c
===================================================================
RCS file: /cvsroot/emacs/emacs/src/keyboard.c,v
retrieving revision 1.882
diff -c -p -r1.882 keyboard.c
*** src/keyboard.c      4 Dec 2006 12:37:55 -0000       1.882
--- src/keyboard.c      13 Dec 2006 09:35:29 -0000
*************** static SIGTYPE interrupt_signal P_ ((int
*** 699,704 ****
--- 699,707 ----
  static void timer_start_idle P_ ((void));
  static void timer_stop_idle P_ ((void));
  static void timer_resume_idle P_ ((void));
+ static SIGTYPE handle_user_signal P_ ((int));
+ static char *find_user_signal_name P_ ((int));
+ static int store_user_signal_events P_ ((void));
  
  /* Nonzero means don't try to suspend even if the operating system seems
     to support it.  */
*************** make_lispy_event (event)
*** 5948,5967 ****
  
      case USER_SIGNAL_EVENT:
        /* A user signal.  */
!       switch (event->code)
        {
!       case 0:
!         return Qsignal;
! #ifdef SIGUSR1
!       case SIGUSR1:
!         return intern ("usr1");
! #endif
! #ifdef SIGUSR2
!       case SIGUSR2:
!         return intern ("usr2");
! #endif
!       default:
!         return make_number (event->code);
        }
  
      case SAVE_SESSION_EVENT:
--- 5951,5966 ----
  
      case USER_SIGNAL_EVENT:
        /* A user signal.  */
!       if (event->code == 0)
!       return Qsignal;
!       else
        {
!         char *name = find_user_signal_name (event->code);
! 
!         if (name)
!           return intern (name);
!         else
!           return make_number (event->code);
        }
  
      case SAVE_SESSION_EVENT:
*************** read_avail_input (expected)
*** 6799,6804 ****
--- 6798,6807 ----
    register int i;
    int nread = 0;
  
+   /* Store pending user signal events, if any.  */
+   if (store_user_signal_events ())
+     expected = 0;
+ 
    if (read_socket_hook)
      {
        int nr;
*************** reinvoke_input_signal ()
*** 7022,7027 ****
--- 7025,7157 ----
  
  
  
+ /* User signal events.  */
+ 
+ struct user_signal_info
+ {
+   /* Signal number.  */
+   int sig;
+ 
+   /* Name of the signal.  */
+   char *name;
+ 
+   /* Number of pending signals.  */
+   int npending;
+ 
+   struct user_signal_info *next;
+ };
+ 
+ /* List of user signals. */
+ static struct user_signal_info *user_signals = NULL;
+ 
+ void
+ add_user_signal (sig, name)
+      int sig;
+      const char *name;
+ {
+   struct user_signal_info *p;
+ 
+   for (p = user_signals; p; p = p->next)
+     if (p->sig == sig)
+       /* Already added.  */
+       return;
+ 
+   p = xmalloc (sizeof (struct user_signal_info));
+   p->sig = sig;
+   p->name = xstrdup (name);
+   p->npending = 0;
+   p->next = user_signals;
+   user_signals = p;
+ 
+   signal (sig, handle_user_signal);
+ }
+ 
+ static SIGTYPE
+ handle_user_signal (sig)
+      int sig;
+ {
+   int old_errno = errno;
+   struct user_signal_info *p;
+ 
+ #if defined (USG) && !defined (POSIX_SIGNALS)
+   /* USG systems forget handlers when they are used;
+      must reestablish each time */
+   signal (sig, handle_user_signal);
+ #endif
+ 
+   SIGNAL_THREAD_CHECK (sig);
+ 
+   for (p = user_signals; p; p = p->next)
+     if (p->sig == sig)
+       {
+       p->npending++;
+ #ifdef SIGIO
+       if (interrupt_input)
+         kill (getpid (), SIGIO);
+       else
+ #endif
+         {
+           /* Tell wait_reading_process_output that it needs to wake
+              up and look around.  */
+           if (input_available_clear_time)
+             EMACS_SET_SECS_USECS (*input_available_clear_time, 0, 0);
+         }
+       break;
+       }
+ 
+   errno = old_errno;
+ }
+ 
+ static char *
+ find_user_signal_name (sig)
+      int sig;
+ {
+   struct user_signal_info *p;
+ 
+   for (p = user_signals; p; p = p->next)
+     if (p->sig == sig)
+       return p->name;
+ 
+   return NULL;
+ }
+ 
+ static int
+ store_user_signal_events ()
+ {
+   struct user_signal_info *p;
+   struct input_event buf;
+   int nstored = 0;
+ 
+   for (p = user_signals; p; p = p->next)
+     if (p->npending > 0)
+       {
+       SIGMASKTYPE mask;
+ 
+       if (nstored == 0)
+         {
+           bzero (&buf, sizeof buf);
+           buf.kind = USER_SIGNAL_EVENT;
+           buf.frame_or_window = selected_frame;
+         }
+       nstored += p->npending;
+ 
+       mask = sigblock (sigmask (p->sig));
+       do
+         {
+           buf.code = 0;
+           kbd_buffer_store_event (&buf);
+           buf.code = p->sig;
+           kbd_buffer_store_event (&buf);
+           p->npending--;
+         }
+       while (p->npending > 0);
+       sigsetmask (mask);
+       }
+ 
+   return nstored;
+ }
+ 
+ 
  static void menu_bar_item P_ ((Lisp_Object, Lisp_Object, Lisp_Object, void*));
  static Lisp_Object menu_bar_one_keymap_changed_items;
  
Index: src/keyboard.h
===================================================================
RCS file: /cvsroot/emacs/emacs/src/keyboard.h,v
retrieving revision 1.73
diff -c -p -r1.73 keyboard.h
*** src/keyboard.h      27 Aug 2006 07:09:14 -0000      1.73
--- src/keyboard.h      13 Dec 2006 09:35:29 -0000
*************** extern void gen_help_event P_ ((Lisp_Obj
*** 344,349 ****
--- 344,350 ----
  extern void kbd_buffer_store_help_event P_ ((Lisp_Object, Lisp_Object));
  extern Lisp_Object menu_item_eval_property P_ ((Lisp_Object));
  extern int  kbd_buffer_events_waiting P_ ((int));
+ extern void add_user_signals P_ ((int, const char *));
  
  /* arch-tag: 769cbade-1ba9-4950-b886-db265b061aa3
     (do not change this comment) */




reply via email to

[Prev in Thread] Current Thread [Next in Thread]