--- a/lib/thread.c +++ b/lib/thread.c @@ -824,13 +824,9 @@ static void thread_free(struct thread_ma XFREE(MTYPE_THREAD, thread); } -static int fd_poll(struct thread_master *m, const struct timeval *timer_wait, - bool *eintr_p) +static int fd_poll(struct thread_master *m, struct pollfd *pfds, nfds_t pfdsize, + nfds_t count, const struct timeval *timer_wait) { - sigset_t origsigs; - unsigned char trash[64]; - nfds_t count = m->handler.copycount; - /* * If timer_wait is null here, that means poll() should block * indefinitely, unless the thread_master has overridden it by setting @@ -861,58 +857,15 @@ static int fd_poll(struct thread_master rcu_assert_read_unlocked(); /* add poll pipe poker */ - assert(count + 1 < m->handler.pfdsize); - m->handler.copy[count].fd = m->io_pipe[0]; - m->handler.copy[count].events = POLLIN; - m->handler.copy[count].revents = 0x00; - - /* We need to deal with a signal-handling race here: we - * don't want to miss a crucial signal, such as SIGTERM or SIGINT, - * that may arrive just before we enter poll(). We will block the - * key signals, then check whether any have arrived - if so, we return - * before calling poll(). If not, we'll re-enable the signals - * in the ppoll() call. - */ - - sigemptyset(&origsigs); - if (m->handle_signals) { - /* Main pthread that handles the app signals */ - if (frr_sigevent_check(&origsigs)) { - /* Signal to process - restore signal mask and return */ - pthread_sigmask(SIG_SETMASK, &origsigs, NULL); - num = -1; - *eintr_p = true; - goto done; - } - } else { - /* Don't make any changes for the non-main pthreads */ - pthread_sigmask(SIG_SETMASK, NULL, &origsigs); - } + assert(count + 1 < pfdsize); + pfds[count].fd = m->io_pipe[0]; + pfds[count].events = POLLIN; + pfds[count].revents = 0x00; -#if defined(HAVE_PPOLL) - struct timespec ts, *tsp; + num = poll(pfds, count + 1, timeout); - if (timeout >= 0) { - ts.tv_sec = timeout / 1000; - ts.tv_nsec = (timeout % 1000) * 1000000; - tsp = &ts; - } else - tsp = NULL; - - num = ppoll(m->handler.copy, count + 1, tsp, &origsigs); - pthread_sigmask(SIG_SETMASK, &origsigs, NULL); -#else - /* Not ideal - there is a race after we restore the signal mask */ - pthread_sigmask(SIG_SETMASK, &origsigs, NULL); - num = poll(m->handler.copy, count + 1, timeout); -#endif - -done: - - if (num < 0 && errno == EINTR) - *eintr_p = true; - - if (num > 0 && m->handler.copy[count].revents != 0 && num--) + unsigned char trash[64]; + if (num > 0 && pfds[count].revents != 0 && num--) while (read(m->io_pipe[0], &trash, sizeof(trash)) > 0) ; @@ -1700,7 +1653,7 @@ struct thread *thread_fetch(struct threa struct timeval zerotime = {0, 0}; struct timeval tv; struct timeval *tw = NULL; - bool eintr_p = false; + int num = 0; do { @@ -1776,14 +1729,14 @@ struct thread *thread_fetch(struct threa pthread_mutex_unlock(&m->mtx); { - eintr_p = false; - num = fd_poll(m, tw, &eintr_p); + num = fd_poll(m, m->handler.copy, m->handler.pfdsize, + m->handler.copycount, tw); } pthread_mutex_lock(&m->mtx); /* Handle any errors received in poll() */ if (num < 0) { - if (eintr_p) { + if (errno == EINTR) { pthread_mutex_unlock(&m->mtx); /* loop around to signal handler */ continue;