Changeset 3535a6e


Ignore:
Timestamp:
May 23, 2011, 8:57:46 PM (10 years ago)
Author:
David Benjamin <davidben@mit.edu>
Branches:
master, release-1.8, release-1.9
Children:
257b9c4
Parents:
959cb85
git-author:
David Benjamin <davidben@mit.edu> (02/26/11 00:15:35)
git-committer:
David Benjamin <davidben@mit.edu> (05/23/11 20:57:46)
Message:
First go at sigwait-based signal handling

Instead of relying on pselect and signal masking to listen for signals,
which glib doesn't support, we spawn a dedicated signal thread that
loops in sigwait. These signals are posted back to the main message loop
which may handle them at will. This avoids the need for complex
reentrant code and sig_atomic_t.

This removes the final pre-select action.

SIGINT doesn't quite work right yet because we can no longer take it in
the middle of an event loop iteration.
Files:
1 added
6 edited

Legend:

Unmodified
Added
Removed
  • Makefile.am

    rce35060 r3535a6e  
    4545     aim.c buddy.c buddylist.c style.c errqueue.c \
    4646     zbuddylist.c popexec.c select.c wcwidth.c \
    47      glib_compat.c mainpanel.c msgwin.c sepbar.c editcontext.c
     47     glib_compat.c mainpanel.c msgwin.c sepbar.c editcontext.c signal.c
    4848
    4949NORMAL_SRCS = filterproc.c window.c windowcb.c
  • functions.c

    r1a30f05 r3535a6e  
    29952995      i--;
    29962996    }
     2997#if 0
     2998    /* FIXME!!! */
    29972999    owl_function_mask_sigint(NULL);
    29983000    if(owl_global_is_interrupted(&g)) {
     
    30043006    }
    30053007    owl_function_unmask_sigint(NULL);
     3008#endif
    30063009  }
    30073010  owl_mainwin_redisplay(owl_global_get_mainwin(&g));
     
    30863089          ret=ZLocateUser(zstr(user), &numlocs, ZAUTH);
    30873090
     3091#if 0
     3092          /* FIXME!! */
    30883093          owl_function_mask_sigint(NULL);
    30893094          if(owl_global_is_interrupted(&g)) {
     
    30963101
    30973102          owl_function_unmask_sigint(NULL);
     3103#endif
    30983104
    30993105          if (ret!=ZERR_NONE) {
  • global.c

    r2c79eae r3535a6e  
    1616
    1717  g_type_init();
     18  g_thread_init(NULL);
    1819
    1920  owl_select_init();
     
    101102
    102103  owl_errqueue_init(&(g->errqueue));
    103   g->got_err_signal=0;
    104104
    105105  owl_zbuddylist_create(&(g->zbuddies));
     
    112112  owl_list_create(&(g->psa_list));
    113113  g->timerlist = NULL;
    114   g->interrupted = FALSE;
    115114  g->kill_buffer = NULL;
    116115}
     
    350349
    351350void owl_global_set_resize_pending(owl_global *g) {
    352   g->resizepending=1;
     351  g->resizepending = true;
    353352}
    354353
     
    450449  /* resize the screen.  If lines or cols is 0 use the terminal size */
    451450  if (!g->resizepending) return;
    452   g->resizepending = 0;
     451  g->resizepending = false;
    453452
    454453  owl_global_get_terminal_size(&g->lines, &g->cols);
     
    826825}
    827826
    828 void owl_global_set_errsignal(owl_global *g, int signum, siginfo_t *siginfo)
    829 {
    830   g->got_err_signal = signum;
    831   if (siginfo) {
    832     g->err_signal_info = *siginfo;
    833   } else {
    834     siginfo_t si;
    835     memset(&si, 0, sizeof(si));
    836     g->err_signal_info = si;
    837   }
    838 }
    839 
    840 int owl_global_get_errsignal_and_clear(owl_global *g, siginfo_t *siginfo)
    841 {
    842   int signum;
    843   if (siginfo && g->got_err_signal) {
    844     *siginfo = g->err_signal_info;
    845   }
    846   signum = g->got_err_signal;
    847   g->got_err_signal = 0;
    848   return signum;
    849 }
    850 
    851 
    852827owl_zbuddylist *owl_global_get_zephyr_buddylist(owl_global *g)
    853828{
     
    888863{
    889864  return &(g->timerlist);
    890 }
    891 
    892 int owl_global_is_interrupted(const owl_global *g) {
    893   return g->interrupted;
    894 }
    895 
    896 void owl_global_set_interrupted(owl_global *g) {
    897   g->interrupted = 1;
    898 }
    899 
    900 void owl_global_unset_interrupted(owl_global *g) {
    901   g->interrupted = 0;
    902865}
    903866
  • owl.c

    r6b4033f r3535a6e  
    354354}
    355355
    356 void sig_handler(int sig, siginfo_t *si, void *data)
    357 {
    358   if (sig==SIGWINCH) {
     356static void sig_handler(int sig, void *data) {
     357  owl_function_debugmsg("Got signal %d", sig);
     358  /* TODO: These don't need to be re-entrant anymore! */
     359  if (sig == SIGWINCH) {
    359360    /* we can't inturrupt a malloc here, so it just sets a flag
    360361     * schedulding a resize for later
    361362     */
    362363    owl_function_resize();
    363   } else if (sig==SIGPIPE || sig==SIGCHLD) {
    364     /* Set a flag and some info that we got the sigpipe
    365      * so we can record that we got it and why... */
    366     owl_global_set_errsignal(&g, sig, si);
    367   } else if (sig==SIGTERM || sig==SIGHUP) {
     364  } else if (sig == SIGPIPE || sig == SIGCHLD) {
     365    owl_function_error("Got unexpected signal: %d %s",
     366                       sig, (sig == SIGPIPE) ? "SIGPIPE" : "SIGCHLD");
     367  } else if (sig == SIGTERM || sig == SIGHUP) {
    368368    owl_function_quit();
    369   }
    370 }
    371 
    372 void sigint_handler(int sig, siginfo_t *si, void *data)
    373 {
    374   owl_global_set_interrupted(&g);
    375 }
    376 
    377 static int owl_errsignal_pre_select_action(owl_ps_action *a, void *data)
    378 {
    379   siginfo_t si;
    380   int signum;
    381   if ((signum = owl_global_get_errsignal_and_clear(&g, &si)) > 0) {
    382     owl_function_error("Got unexpected signal: %d %s  (code: %d band: %ld  errno: %d)",
    383         signum, signum==SIGPIPE?"SIGPIPE":"SIG????",
    384         si.si_code, si.si_band, si.si_errno);
    385   }
    386   return 0;
     369  } else if (sig == SIGINT) {
     370    owl_input in;
     371    in.ch = in.uch = owl_global_get_startup_tio(&g)->c_cc[VINTR];
     372    owl_process_input_char(in);
     373  }
    387374}
    388375
    389376void owl_register_signal_handlers(void) {
    390   struct sigaction sigact;
    391 
    392   /* signal handler */
    393   /*sigact.sa_handler=sig_handler;*/
    394   sigact.sa_sigaction=sig_handler;
    395   sigemptyset(&sigact.sa_mask);
    396   sigact.sa_flags=SA_SIGINFO;
    397   sigaction(SIGWINCH, &sigact, NULL);
    398   sigaction(SIGALRM, &sigact, NULL);
    399   sigaction(SIGPIPE, &sigact, NULL);
    400   sigaction(SIGTERM, &sigact, NULL);
    401   sigaction(SIGHUP, &sigact, NULL);
    402 
    403   sigact.sa_sigaction=sigint_handler;
    404   sigaction(SIGINT, &sigact, NULL);
     377  sigset_t sigset;
     378
     379  sigemptyset(&sigset);
     380  sigaddset(&sigset, SIGWINCH);
     381  sigaddset(&sigset, SIGALRM);
     382  sigaddset(&sigset, SIGPIPE);
     383  sigaddset(&sigset, SIGTERM);
     384  sigaddset(&sigset, SIGHUP);
     385  sigaddset(&sigset, SIGINT);
     386
     387  owl_signal_init(&sigset, sig_handler, NULL);
    405388}
    406389
     
    479462  g.load_initial_subs = opts.load_initial_subs;
    480463
    481   owl_register_signal_handlers();
    482464  owl_start_curses();
    483465
     
    491473  g_strfreev(argv_copy);
    492474  owl_global_set_haveaim(&g);
     475
     476  owl_register_signal_handlers();
    493477
    494478  /* register STDIN dispatch; throw away return, we won't need it */
     
    591575  g_source_unref(source);
    592576
    593   owl_select_add_pre_select_action(owl_errsignal_pre_select_action, NULL, NULL);
    594 
    595577  owl_function_debugmsg("startup: entering main loop");
    596578  owl_select_run_loop();
  • owl.h

    r2c79eae r3535a6e  
    592592  gulong typwin_erase_id;
    593593  int rightshift;
    594   volatile sig_atomic_t resizepending;
     594  bool resizepending;
    595595  char *homedir;
    596596  char *confdir;
     
    627627  int haveaim;
    628628  int ignoreaimlogin;
    629   volatile sig_atomic_t got_err_signal; /* 1 if we got an unexpected signal */
    630   volatile siginfo_t err_signal_info;
    631629  owl_zbuddylist zbuddies;
    632630  GList *zaldlist;
     
    638636  owl_timer *aim_nop_timer;
    639637  int load_initial_subs;
    640   volatile sig_atomic_t interrupted;
    641638  FILE *debug_file;
    642639  char *kill_buffer;
  • select.c

    r2c79eae r3535a6e  
    331331    owl_function_makemsg("Unable to handle keypress");
    332332  }
    333 }
    334 
    335 void owl_select_mask_signals(sigset_t *oldmask) {
    336   sigset_t set;
    337 
    338   sigemptyset(&set);
    339   sigaddset(&set, SIGWINCH);
    340   sigaddset(&set, SIGALRM);
    341   sigaddset(&set, SIGPIPE);
    342   sigaddset(&set, SIGTERM);
    343   sigaddset(&set, SIGHUP);
    344   sigaddset(&set, SIGINT);
    345   sigprocmask(SIG_BLOCK, &set, oldmask);
    346 }
    347 
    348 void owl_select_handle_intr(sigset_t *restore)
    349 {
    350   owl_input in;
    351 
    352   owl_global_unset_interrupted(&g);
    353 
    354   sigprocmask(SIG_SETMASK, restore, NULL);
    355 
    356   in.ch = in.uch = owl_global_get_startup_tio(&g)->c_cc[VINTR];
    357   owl_process_input_char(in);
    358333}
    359334
Note: See TracChangeset for help on using the changeset viewer.