mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2024-11-10 23:32:09 +00:00
[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:
parent
243840daa7
commit
486728a4bd
2 changed files with 9 additions and 7 deletions
|
@ -577,11 +577,11 @@ dump_command (qwaq_resources_t *res, int len)
|
||||||
void
|
void
|
||||||
qwaq_init_timeout (struct timespec *timeout, long time)
|
qwaq_init_timeout (struct timespec *timeout, long time)
|
||||||
{
|
{
|
||||||
#define SEC 1000000000
|
#define SEC 1000000000L
|
||||||
struct timeval now;
|
struct timeval now;
|
||||||
gettimeofday(&now, 0);
|
gettimeofday(&now, 0);
|
||||||
timeout->tv_sec = now.tv_sec;
|
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) {
|
if (timeout->tv_nsec > SEC) {
|
||||||
timeout->tv_sec += timeout->tv_nsec / SEC;
|
timeout->tv_sec += timeout->tv_nsec / 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);
|
pthread_mutex_lock (&res->command_cond.mut);
|
||||||
qwaq_init_timeout (&timeout, 20 * 1000000);
|
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,
|
ret = pthread_cond_timedwait (&res->command_cond.rcond,
|
||||||
&res->command_cond.mut, &timeout);
|
&res->command_cond.mut, &timeout);
|
||||||
}
|
}
|
||||||
|
@ -700,23 +700,25 @@ get_event (qwaq_resources_t *res, qwaq_event_t *event)
|
||||||
{
|
{
|
||||||
struct timespec timeout;
|
struct timespec timeout;
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
int was_event = 0;
|
||||||
|
|
||||||
pthread_mutex_lock (&res->event_cond.mut);
|
pthread_mutex_lock (&res->event_cond.mut);
|
||||||
qwaq_init_timeout (&timeout, 20 * 1000000);
|
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,
|
ret = pthread_cond_timedwait (&res->event_cond.rcond,
|
||||||
&res->event_cond.mut, &timeout);
|
&res->event_cond.mut, &timeout);
|
||||||
}
|
}
|
||||||
if (event) {
|
if (event) {
|
||||||
if (ret != ETIMEDOUT) {
|
if (ret == 0) {
|
||||||
RB_READ_DATA (res->event_queue, event, 1);
|
RB_READ_DATA (res->event_queue, event, 1);
|
||||||
|
was_event = 1;
|
||||||
} else {
|
} else {
|
||||||
event->what = qe_none;
|
event->what = qe_none;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pthread_cond_broadcast (&res->event_cond.wcond);
|
pthread_cond_broadcast (&res->event_cond.wcond);
|
||||||
pthread_mutex_unlock (&res->event_cond.mut);
|
pthread_mutex_unlock (&res->event_cond.mut);
|
||||||
return ret != ETIMEDOUT;
|
return was_event;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int need_endwin;
|
static int need_endwin;
|
||||||
|
|
|
@ -77,7 +77,7 @@ add_event (qwaq_resources_t *res, qwaq_event_t *event)
|
||||||
|
|
||||||
pthread_mutex_lock (&res->event_cond.mut);
|
pthread_mutex_lock (&res->event_cond.mut);
|
||||||
qwaq_init_timeout (&timeout, 5000 * 1000000L);
|
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,
|
ret = pthread_cond_timedwait (&res->event_cond.wcond,
|
||||||
&res->event_cond.mut, &timeout);
|
&res->event_cond.mut, &timeout);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue