[qwaq] Be a little paranoid about cond wait timeouts

I'd left qwaq-curses running overnight and found it locked up: both
threads were looping because pthread_cond_timedwait was returning
EINVAL. Thus bail if anything other than 0 is returned, and try to
ensure tv_nsec is in the range 0..999999999
This commit is contained in:
Bill Currie 2020-03-22 08:35:37 +09:00
parent 243840daa7
commit 486728a4bd
2 changed files with 9 additions and 7 deletions

View file

@ -577,11 +577,11 @@ dump_command (qwaq_resources_t *res, int len)
void
qwaq_init_timeout (struct timespec *timeout, long time)
{
#define SEC 1000000000
#define SEC 1000000000L
struct timeval now;
gettimeofday(&now, 0);
timeout->tv_sec = now.tv_sec;
timeout->tv_nsec = now.tv_usec * 1000 + time;
timeout->tv_nsec = now.tv_usec * 1000L + time;
if (timeout->tv_nsec > SEC) {
timeout->tv_sec += timeout->tv_nsec / SEC;
timeout->tv_nsec %= SEC;
@ -598,7 +598,7 @@ process_commands (qwaq_resources_t *res)
pthread_mutex_lock (&res->command_cond.mut);
qwaq_init_timeout (&timeout, 20 * 1000000);
while (RB_DATA_AVAILABLE (res->command_queue) < 2 && ret != ETIMEDOUT) {
while (RB_DATA_AVAILABLE (res->command_queue) < 2 && ret == 0) {
ret = pthread_cond_timedwait (&res->command_cond.rcond,
&res->command_cond.mut, &timeout);
}
@ -700,23 +700,25 @@ get_event (qwaq_resources_t *res, qwaq_event_t *event)
{
struct timespec timeout;
int ret = 0;
int was_event = 0;
pthread_mutex_lock (&res->event_cond.mut);
qwaq_init_timeout (&timeout, 20 * 1000000);
while (RB_DATA_AVAILABLE (res->event_queue) < 1 && ret != ETIMEDOUT) {
while (RB_DATA_AVAILABLE (res->event_queue) < 1 && ret == 0) {
ret = pthread_cond_timedwait (&res->event_cond.rcond,
&res->event_cond.mut, &timeout);
}
if (event) {
if (ret != ETIMEDOUT) {
if (ret == 0) {
RB_READ_DATA (res->event_queue, event, 1);
was_event = 1;
} else {
event->what = qe_none;
}
}
pthread_cond_broadcast (&res->event_cond.wcond);
pthread_mutex_unlock (&res->event_cond.mut);
return ret != ETIMEDOUT;
return was_event;
}
static int need_endwin;

View file

@ -77,7 +77,7 @@ add_event (qwaq_resources_t *res, qwaq_event_t *event)
pthread_mutex_lock (&res->event_cond.mut);
qwaq_init_timeout (&timeout, 5000 * 1000000L);
while (RB_SPACE_AVAILABLE (res->event_queue) < 1 && ret != ETIMEDOUT) {
while (RB_SPACE_AVAILABLE (res->event_queue) < 1 && ret == 0) {
ret = pthread_cond_timedwait (&res->event_cond.wcond,
&res->event_cond.mut, &timeout);
}