Mercurial > hg > freeDiameter
changeset 1376:b8afaf63f65a
Handle case where pthread_cond_timedwait returns EINVAL if abstime
has passed before it was called.
author | Thomas Klausner <tk@giga.or.at> |
---|---|
date | Thu, 20 Jun 2019 11:33:29 +0200 |
parents | 2bd83cd4d2b2 |
children | ce257e43085d |
files | libfdproto/sessions.c |
diffstat | 1 files changed, 20 insertions(+), 5 deletions(-) [+] |
line wrap: on
line diff
--- a/libfdproto/sessions.c Thu Jun 20 10:37:54 2019 +0200 +++ b/libfdproto/sessions.c Thu Jun 20 11:33:29 2019 +0200 @@ -206,12 +206,27 @@ /* If first session is not expired, we just wait until it happens */ if ( TS_IS_INFERIOR( &now, &first->timeout ) ) { - CHECK_POSIX_DO2( pthread_cond_timedwait( &exp_cond, &exp_lock, &first->timeout ), - ETIMEDOUT, /* ETIMEDOUT is a normal error, continue */, - /* on other error, */ break ); + int ret; - /* on wakeup, loop */ - goto again; + ret = pthread_cond_timedwait(&exp_cond, &exp_lock, &first->timeout); + switch (ret) { + case 0: + case ETIMEDOUT: + /* on wakeup or time-out, loop */ + goto again; + case EINVAL: + if (clock_gettime(CLOCK_REALTIME, &now) < 0) { + break; + } + if (TS_IS_INFERIOR(&now, &first->timeout)) { + TRACE_DEBUG(FULL, "'pthread_cond_timedwait(&exp_cond, &exp_lock, &first->timeout)' : timer expired before loop could start"); + goto again; + } + /* FALLTHROUGH */ + default: + TRACE_ERROR("ERROR: in 'pthread_cond_timedwait(&exp_cond, &exp_lock, &first->timeout)' :\t%s", strerror(ret)); + break; + } } /* Now, the first session in the list is expired; destroy it */