diff options
author | Gonzalo Paniagua Javier <gonzalo.mono@gmail.com> | 2010-04-09 08:36:35 +0400 |
---|---|---|
committer | Gonzalo Paniagua Javier <gonzalo.mono@gmail.com> | 2010-04-09 08:36:35 +0400 |
commit | d32b4828b324cd55121cabacdb88da2a71082190 (patch) | |
tree | ba35f310afeb05f6e506f2a1479f88357bcd467d | |
parent | fcd426cedbf35d3a60dc0bb60288329de3fefeb9 (diff) |
2010-04-09 Gonzalo Paniagua Javier <gonzalo@novell.com>
* mono-semaphore.c: account for the time already spent in wait if
interrupted.
svn path=/branches/mono-2-6/mono/; revision=155120
-rw-r--r-- | mono/utils/ChangeLog | 5 | ||||
-rw-r--r-- | mono/utils/mono-semaphore.c | 21 |
2 files changed, 24 insertions, 2 deletions
diff --git a/mono/utils/ChangeLog b/mono/utils/ChangeLog index 291c8800b42..e9bda8c7fec 100644 --- a/mono/utils/ChangeLog +++ b/mono/utils/ChangeLog @@ -1,3 +1,8 @@ +2010-04-09 Gonzalo Paniagua Javier <gonzalo@novell.com> + + * mono-semaphore.c: account for the time already spent in wait if + interrupted. + 2010-04-09 Zoltan Varga <vargaz@gmail.com> * mono-time.c (get_boot_time): Applied more openbsd changes from Robert Nagy diff --git a/mono/utils/mono-semaphore.c b/mono/utils/mono-semaphore.c index b7b0e894154..f4d5297109b 100644 --- a/mono/utils/mono-semaphore.c +++ b/mono/utils/mono-semaphore.c @@ -30,6 +30,7 @@ # define WAIT_BLOCK(a,b) sem_timedwait (a, b) # endif +#define NSEC_PER_SEC 1000000000 int mono_sem_timedwait (MonoSemType *sem, guint32 timeout_ms, gboolean alertable) { @@ -50,8 +51,8 @@ mono_sem_timedwait (MonoSemType *sem, guint32 timeout_ms, gboolean alertable) gettimeofday (&t, NULL); ts.tv_sec = timeout_ms / 1000 + t.tv_sec; ts.tv_nsec = (timeout_ms % 1000) * 1000000 + t.tv_usec * 1000; - while (ts.tv_nsec > 1000000000) { - ts.tv_nsec -= 1000000000; + while (ts.tv_nsec > NSEC_PER_SEC) { + ts.tv_nsec -= NSEC_PER_SEC; ts.tv_sec++; } #if defined(__OpenBSD__) @@ -69,9 +70,25 @@ mono_sem_timedwait (MonoSemType *sem, guint32 timeout_ms, gboolean alertable) #else copy = ts; while ((res = WAIT_BLOCK (sem, &ts) == -1) && errno == EINTR) { + struct timeval current; if (alertable) return -1; + gettimeofday (¤t, NULL); ts = copy; + ts.tv_sec -= (current.tv_sec - t.tv_sec); + ts.tv_nsec -= (current.tv_usec - t.tv_usec) * 1000; + if (ts.tv_nsec < 0) { + if (ts.tv_sec <= 0) { + ts.tv_nsec = 0; + } else { + ts.tv_sec--; + ts.tv_nsec += NSEC_PER_SEC; + } + } + if (ts.tv_sec < 0) { + ts.tv_sec = 0; + ts.tv_nsec = 0; + } } #endif return res; |