Changeset f97c1a6 for owl.c


Ignore:
Timestamp:
May 23, 2011, 9:09:44 PM (10 years ago)
Author:
David Benjamin <davidben@mit.edu>
Branches:
master, release-1.8, release-1.9
Children:
33b6431b
Parents:
4c7c21f (diff), 1d21d9f (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
Message:
Merge branch 'g_main_loop'

The logic in owl_select_prune_bad_fds still needs to be reimplemented.

Conflicts:
	configure.ac
	owl.c
	select.c
File:
1 edited

Legend:

Unmodified
Added
Removed
  • owl.c

    r3b8a563 rf97c1a6  
    160160 * was ignored due to user settings or otherwise.
    161161 */
    162 int owl_process_message(owl_message *m) {
     162static int owl_process_message(owl_message *m) {
    163163  const owl_filter *f;
    164164  /* if this message it on the puntlist, nuke it and continue */
     
    245245}
    246246
     247static gboolean owl_process_messages_prepare(GSource *source, int *timeout) {
     248  *timeout = -1;
     249  return owl_global_messagequeue_pending(&g);
     250}
     251
     252static gboolean owl_process_messages_check(GSource *source) {
     253  return owl_global_messagequeue_pending(&g);
     254}
     255
    247256/*
    248257 * Process any new messages we have waiting in the message queue.
    249  * Returns 1 if any messages were added to the message list, and 0 otherwise.
    250258 */
    251 int owl_process_messages(owl_ps_action *d, void *p)
    252 {
     259static gboolean owl_process_messages_dispatch(GSource *source, GSourceFunc callback, gpointer user_data) {
    253260  int newmsgs=0;
    254261  int followlast = owl_global_should_followlast(&g);
     
    274281    owl_mainwin_redisplay(owl_global_get_mainwin(&g));
    275282  }
    276   return newmsgs;
     283  return TRUE;
     284}
     285
     286static GSourceFuncs owl_process_messages_funcs = {
     287  owl_process_messages_prepare,
     288  owl_process_messages_check,
     289  owl_process_messages_dispatch,
     290  NULL
     291};
     292
     293void owl_process_input_char(owl_input j)
     294{
     295  int ret;
     296
     297  owl_global_set_lastinputtime(&g, time(NULL));
     298  ret = owl_keyhandler_process(owl_global_get_keyhandler(&g), j);
     299  if (ret!=0 && ret!=1) {
     300    owl_function_makemsg("Unable to handle keypress");
     301  }
    277302}
    278303
     
    334359}
    335360
    336 void sig_handler(int sig, siginfo_t *si, void *data)
    337 {
    338   if (sig==SIGWINCH) {
    339     /* we can't inturrupt a malloc here, so it just sets a flag
    340      * schedulding a resize for later
    341      */
     361static void sig_handler_main_thread(void *data) {
     362  int sig = GPOINTER_TO_INT(data);
     363
     364  owl_function_debugmsg("Got signal %d", sig);
     365  if (sig == SIGWINCH) {
    342366    owl_function_resize();
    343   } else if (sig==SIGPIPE || sig==SIGCHLD) {
    344     /* Set a flag and some info that we got the sigpipe
    345      * so we can record that we got it and why... */
    346     owl_global_set_errsignal(&g, sig, si);
    347   } else if (sig==SIGTERM || sig==SIGHUP) {
     367  } else if (sig == SIGTERM || sig == SIGHUP) {
    348368    owl_function_quit();
    349   }
    350 }
    351 
    352 void sigint_handler(int sig, siginfo_t *si, void *data)
    353 {
    354   owl_global_set_interrupted(&g);
    355 }
    356 
    357 static int owl_errsignal_pre_select_action(owl_ps_action *a, void *data)
    358 {
    359   siginfo_t si;
    360   int signum;
    361   if ((signum = owl_global_get_errsignal_and_clear(&g, &si)) > 0) {
    362     owl_function_error("Got unexpected signal: %d %s  (code: %d band: %ld  errno: %d)",
    363         signum, signum==SIGPIPE?"SIGPIPE":"SIG????",
    364         si.si_code, si.si_band, si.si_errno);
    365   }
    366   return 0;
    367 }
     369  } else if (sig == SIGINT && owl_global_take_interrupt(&g)) {
     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  }
     374}
     375
     376static void sig_handler(const siginfo_t *siginfo, void *data) {
     377  /* If it was an interrupt, set a flag so we can handle it earlier if
     378   * needbe. sig_handler_main_thread will check the flag to make sure
     379   * no one else took it. */
     380  if (siginfo->si_signo == SIGINT) {
     381    owl_global_add_interrupt(&g);
     382  }
     383  /* Send a message to the main thread. */
     384  owl_select_post_task(sig_handler_main_thread,
     385                       GINT_TO_POINTER(siginfo->si_signo), NULL);
     386}
     387
     388#define CHECK_RESULT(s, syscall) \
     389  G_STMT_START {                 \
     390    if ((syscall) != 0) {        \
     391      perror((s));               \
     392      exit(1);                   \
     393    }                            \
     394  } G_STMT_END
    368395
    369396void owl_register_signal_handlers(void) {
    370   struct sigaction sigact;
    371 
    372   /* signal handler */
    373   /*sigact.sa_handler=sig_handler;*/
    374   sigact.sa_sigaction=sig_handler;
    375   sigemptyset(&sigact.sa_mask);
    376   sigact.sa_flags=SA_SIGINFO;
    377   sigaction(SIGWINCH, &sigact, NULL);
    378   sigaction(SIGALRM, &sigact, NULL);
    379   sigaction(SIGPIPE, &sigact, NULL);
    380   sigaction(SIGTERM, &sigact, NULL);
    381   sigaction(SIGHUP, &sigact, NULL);
    382 
    383   sigact.sa_sigaction=sigint_handler;
    384   sigaction(SIGINT, &sigact, NULL);
     397  struct sigaction sig_ignore = { .sa_handler = SIG_IGN };
     398  struct sigaction sig_default = { .sa_handler = SIG_DFL };
     399  sigset_t sigset;
     400  int ret, i;
     401  const int signals[] = { SIGABRT, SIGBUS, SIGCHLD, SIGFPE, SIGHUP, SIGILL,
     402                          SIGINT, SIGQUIT, SIGSEGV, SIGTERM, SIGWINCH };
     403
     404  /* Sanitize our signals; the mask and dispositions from our parent
     405   * aren't really useful. Signal list taken from equivalent code in
     406   * Chromium. */
     407  CHECK_RESULT("sigemptyset", sigemptyset(&sigset));
     408  if ((ret = pthread_sigmask(SIG_SETMASK, &sigset, NULL)) != 0) {
     409    errno = ret;
     410    perror("pthread_sigmask");
     411  }
     412  for (i = 0; i < G_N_ELEMENTS(signals); i++) {
     413    CHECK_RESULT("sigaction", sigaction(signals[i], &sig_default, NULL));
     414  }
     415
     416  /* Turn off SIGPIPE; we check the return value of write. */
     417  CHECK_RESULT("sigaction", sigaction(SIGPIPE, &sig_ignore, NULL));
     418
     419  /* Register some signals with the signal thread. */
     420  CHECK_RESULT("sigaddset", sigaddset(&sigset, SIGWINCH));
     421  CHECK_RESULT("sigaddset", sigaddset(&sigset, SIGTERM));
     422  CHECK_RESULT("sigaddset", sigaddset(&sigset, SIGHUP));
     423  CHECK_RESULT("sigaddset", sigaddset(&sigset, SIGINT));
     424  owl_signal_init(&sigset, sig_handler, NULL);
    385425}
    386426
     
    436476#endif /* OWL_STDERR_REDIR */
    437477
    438 static int owl_refresh_pre_select_action(owl_ps_action *a, void *data)
    439 {
    440   owl_colorpair_mgr *cpmgr;
    441 
    442   /* if a resize has been scheduled, deal with it */
    443   owl_global_check_resize(&g);
    444   /* update the terminal if we need to */
    445   owl_window_redraw_scheduled();
    446   /* On colorpair shortage, reset and redraw /everything/. NOTE: if we
    447    * still overflow, this be useless work. With 8-colors, we get 64
    448    * pairs. With 256-colors, we get 32768 pairs with ext-colors
    449    * support and 256 otherwise. */
    450   cpmgr = owl_global_get_colorpair_mgr(&g);
    451   if (cpmgr->overflow) {
    452     owl_function_debugmsg("colorpairs: used all %d pairs; reset pairs and redraw.",
    453                           owl_util_get_colorpairs());
    454     owl_fmtext_reset_colorpairs(cpmgr);
    455     owl_function_full_redisplay();
    456     owl_window_redraw_scheduled();
    457   }
    458   return 0;
    459 }
    460 
    461 
    462478int main(int argc, char **argv, char **env)
    463479{
     
    468484  const char *dir;
    469485  owl_options opts;
     486  GSource *source;
    470487
    471488  if (!GLIB_CHECK_VERSION (2, 12, 0))
     
    482499  g.load_initial_subs = opts.load_initial_subs;
    483500
    484   owl_register_signal_handlers();
    485501  owl_start_curses();
    486502
     
    493509  g_strfreev(argv_copy);
    494510  owl_global_set_haveaim(&g);
     511
     512  owl_register_signal_handlers();
    495513
    496514  /* register STDIN dispatch; throw away return, we won't need it */
     
    585603  owl_global_push_context(&g, OWL_CTX_INTERACTIVE|OWL_CTX_RECV, NULL, "recv", NULL);
    586604
    587   owl_select_add_pre_select_action(owl_refresh_pre_select_action, NULL, NULL);
    588   owl_select_add_pre_select_action(owl_process_messages, NULL, NULL);
    589   owl_select_add_pre_select_action(owl_errsignal_pre_select_action, NULL, NULL);
     605  source = owl_window_redraw_source_new();
     606  g_source_attach(source, NULL);
     607  g_source_unref(source);
     608
     609  source = g_source_new(&owl_process_messages_funcs, sizeof(GSource));
     610  g_source_attach(source, NULL);
     611  g_source_unref(source);
    590612
    591613  owl_function_debugmsg("startup: entering main loop");
     
    594616  /* Shut down everything. */
    595617  owl_zephyr_shutdown();
     618  owl_signal_shutdown();
    596619  owl_shutdown_curses();
    597620  return 0;
Note: See TracChangeset for help on using the changeset viewer.