2
0
mirror of https://github.com/openvswitch/ovs synced 2025-08-31 14:25:26 +00:00

cfg: Fix implementation of timeout in attempting to lock the config file.

Without removing SA_RESTART from the SIGALRM handler, the fcntl call will
never return, even after the signal handler is invoked and returns.

We haven't seen a problem in practice, at least not recently, but that's
probably just luck combined with not holding the configuration file lock
for very long.
This commit is contained in:
Ben Pfaff
2009-10-15 10:42:59 -07:00
parent e7cfedd6de
commit dc81071d9f
3 changed files with 47 additions and 6 deletions

View File

@@ -44,6 +44,7 @@ static struct timeval now;
static time_t deadline = TIME_MIN;
static void setup_timer(void);
static void setup_signal(int flags);
static void sigalrm_handler(int);
static void refresh_if_ticked(void);
static time_t time_add(time_t, time_t);
@@ -56,7 +57,6 @@ static void log_poll_interval(long long int last_wakeup,
void
time_init(void)
{
struct sigaction sa;
if (inited) {
return;
}
@@ -67,17 +67,49 @@ time_init(void)
gettimeofday(&now, NULL);
tick = false;
/* Set up signal handler. */
setup_signal(SA_RESTART);
setup_timer();
}
static void
setup_signal(int flags)
{
struct sigaction sa;
memset(&sa, 0, sizeof sa);
sa.sa_handler = sigalrm_handler;
sigemptyset(&sa.sa_mask);
sa.sa_flags = SA_RESTART;
sa.sa_flags = flags;
if (sigaction(SIGALRM, &sa, NULL)) {
ovs_fatal(errno, "sigaction(SIGALRM) failed");
}
}
/* Set up periodic signal. */
setup_timer();
/* Remove SA_RESTART from the flags for SIGALRM, so that any system call that
* is interrupted by the periodic timer interrupt will return EINTR instead of
* continuing after the signal handler returns.
*
* time_disable_restart() and time_enable_restart() may be usefully wrapped
* around function calls that might otherwise block forever unless interrupted
* by a signal, e.g.:
*
* time_disable_restart();
* fcntl(fd, F_SETLKW, &lock);
* time_enable_restart();
*/
void
time_disable_restart(void)
{
setup_signal(0);
}
/* Add SA_RESTART to the flags for SIGALRM, so that any system call that
* is interrupted by the periodic timer interrupt will continue after the
* signal handler returns instead of returning EINTR. */
void
time_enable_restart(void)
{
setup_signal(SA_RESTART);
}
static void