Changeset 0cb6c26


Ignore:
Timestamp:
May 5, 2009, 1:30:07 AM (16 years ago)
Author:
Nelson Elhage <nelhage@mit.edu>
Branches:
master, release-1.10, release-1.4, release-1.5, release-1.6, release-1.7, release-1.8, release-1.9
Children:
1e6e74e
Parents:
e0473d2
Message:
Fix a race that could cause us to miss a SIGINT

When I refactored the previous commits to unmask SIGINT in
owl_global_is_interrupted, I accidentally opened a window for us to miss
a SIGINT for a cycle of the event loop if it arrived in owl_select()
between a call to that functuon and pselect().

Undo that refactoring to make is_interrupted() just poll the flag, add
owl_function_(un)mask_sigint() for convenience, and use them in the
relevant locations.
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • functions.c

    rbf66f4e r0cb6c26  
    29902990  int viewsize, i, curmsg, start;
    29912991  owl_message *m;
    2992   sigset_t intr;
    2993   sigemptyset(&intr);
    2994   sigaddset(&intr, SIGINT);
    29952992
    29962993  v=owl_global_get_current_view(&g);
     
    30353032      i--;
    30363033    }
    3037     sigprocmask(SIG_BLOCK, &intr, NULL);
     3034    owl_function_mask_sigint(NULL);
    30383035    if(owl_global_is_interrupted(&g)) {
    30393036      owl_global_unset_interrupted(&g);
     3037      owl_function_unmask_sigint(NULL);
    30403038      owl_function_makemsg("Search interrupted!");
    30413039      owl_mainwin_redisplay(owl_global_get_mainwin(&g));
    30423040      return;
    30433041    }
     3042    owl_function_unmask_sigint(NULL);
    30443043  }
    30453044  owl_mainwin_redisplay(owl_global_get_mainwin(&g));
     
    35173516     return COLORS;
    35183517}
     3518
     3519void owl_function_mask_sigint(sigset_t *oldmask) {
     3520  sigset_t intr;
     3521
     3522  sigemptyset(&intr);
     3523  sigaddset(&intr, SIGINT);
     3524  sigprocmask(SIG_BLOCK, &intr, oldmask);
     3525}
     3526
     3527void owl_function_unmask_sigint(sigset_t *oldmask) {
     3528  sigset_t intr;
     3529
     3530  sigemptyset(&intr);
     3531  sigaddset(&intr, SIGINT);
     3532  sigprocmask(SIG_UNBLOCK, &intr, oldmask);
     3533}
  • global.c

    radee9cc r0cb6c26  
    936936}
    937937
    938 /*
    939  * Note: This must be called with SIGINT masked in order to avoid
    940  * races. This will unset the interrupt flag and unblock SIGINT before
    941  * returning.
    942  */
    943938int owl_global_is_interrupted(owl_global *g) {
    944   int interrupted;
    945   sigset_t intr;
    946   sigemptyset(&intr);
    947   sigaddset(&intr, SIGINT);
    948 
    949   interrupted = g->interrupted;
    950   g->interrupted = 0;
    951 
    952   sigprocmask(SIG_UNBLOCK, &intr, NULL);
    953   return interrupted;
     939  return g->interrupted;
    954940}
    955941
  • select.c

    r3a84694 r0cb6c26  
    290290{
    291291  owl_input in;
     292
     293  owl_global_unset_interrupted(&g);
     294  owl_function_unmask_sigint(NULL);
     295
    292296  in.ch = in.uch = owl_global_get_startup_tio(&g)->c_cc[VINTR];
    293297  owl_process_input_char(in);
     
    301305  fd_set aim_rfds, aim_wfds;
    302306  struct timespec timeout;
    303   sigset_t mask, intr;
    304 
    305   sigemptyset(&intr);
    306   sigaddset(&intr, SIGINT);
     307  sigset_t mask;
    307308
    308309  owl_select_process_timers(&timeout);
    309310
    310   sigprocmask(SIG_BLOCK, &intr, &mask);
     311  owl_function_mask_sigint(&mask);
    311312  if(owl_global_is_interrupted(&g)) {
    312      owl_select_handle_intr();
     313    owl_select_handle_intr();
    313314    return;
    314315  }
     
    352353  }
    353354
    354   sigprocmask(SIG_UNBLOCK, &intr, NULL);
     355  owl_function_unmask_sigint(NULL);
    355356
    356357  if(ret > 0) {
Note: See TracChangeset for help on using the changeset viewer.