diff options
| author | Bent Bisballe Nyeng <deva@aasimon.org> | 2016-04-24 21:39:16 +0200 | 
|---|---|---|
| committer | Bent Bisballe Nyeng <deva@aasimon.org> | 2016-04-24 21:39:41 +0200 | 
| commit | 32463cb2f19c0f1af4edddb396f9ea0abf5147e5 (patch) | |
| tree | 5e1406f846d0ff3829ff3db7d1664fe4ec543680 /src | |
| parent | ec9f9cfe169f7fca3083b5792f9d72dbf3af7f08 (diff) | |
Fix broken timed_wait implementation.
Diffstat (limited to 'src')
| -rw-r--r-- | src/semaphore.cc | 26 | 
1 files changed, 19 insertions, 7 deletions
| diff --git a/src/semaphore.cc b/src/semaphore.cc index 6172251..ea88456 100644 --- a/src/semaphore.cc +++ b/src/semaphore.cc @@ -29,6 +29,7 @@  #include <hugin.hpp>  #include <limits>  #include <assert.h> +#include <string.h>  #ifdef WIN32  #include <windows.h> @@ -58,6 +59,7 @@ Semaphore::Semaphore(std::size_t initial_count)  	                                 nullptr); // unnamed semaphore  #else  	const int pshared = 0; +	memset(&prv->semaphore, 0, sizeof(sem_t));  	sem_init(&prv->semaphore, pshared, initial_count);  #endif  } @@ -93,15 +95,25 @@ bool Semaphore::wait(const std::chrono::milliseconds& timeout)  	assert(ret == WAIT_OBJECT_0);  #else -	struct timespec t = { -		// Whole seconds: -		(time_t)(timeout.count() / 1000), +	struct timespec ts; -		// Remainder as nanoseconds: -		(long)((timeout.count() - ((timeout.count() / 1000) * 1000)) * 1000000) -	}; +	// Get current time +	clock_gettime(CLOCK_REALTIME, &ts); -	int ret = sem_timedwait(&prv->semaphore, &t); +	// Add timeout +	time_t seconds = (time_t)(timeout.count() / 1000); +	ts.tv_sec += seconds; +	ts.tv_nsec += (long)((timeout.count() - (seconds * 1000)) * 1000000); + +	// Make sure we don't overflow the nanoseconds. +	constexpr long nsec = 1000000000LL; +	if(ts.tv_nsec >= nsec) +	{ +		ts.tv_nsec -= nsec; +		ts.tv_sec += 1; +	} + +	int ret = sem_timedwait(&prv->semaphore, &ts);  	if(ret < 0)  	{  		if(errno == ETIMEDOUT) | 
