diff options
| author | Bent Bisballe Nyeng <deva@aasimon.org> | 2016-04-13 18:30:56 +0200 | 
|---|---|---|
| committer | Bent Bisballe Nyeng <deva@aasimon.org> | 2016-04-13 18:30:56 +0200 | 
| commit | fb7bb2ee352cf83a7596a7ed7ba2913a2257e540 (patch) | |
| tree | 7f45c45563dd13233061d25a96967c4b1e9958c5 /src/semaphore.cc | |
| parent | 057ef1d83ba263fb2adf1aa86f8e281ab0065c43 (diff) | |
New Semaphore method wait with timeout.
Diffstat (limited to 'src/semaphore.cc')
| -rw-r--r-- | src/semaphore.cc | 96 | 
1 files changed, 55 insertions, 41 deletions
| diff --git a/src/semaphore.cc b/src/semaphore.cc index cd29bbf..3a4f6c9 100644 --- a/src/semaphore.cc +++ b/src/semaphore.cc @@ -27,87 +27,101 @@  #include "semaphore.h"  #include <hugin.hpp> -  #include <limits> +#include <assert.h>  #ifdef WIN32  #include <windows.h>  #else -// Make sure we don't include /this/ file... +// Make sure we don't include /this/ files header...  #include <../include/semaphore.h> +#include <errno.h> +#include <stdio.h>  #endif  struct semaphore_private_t {  #ifdef WIN32 -  HANDLE semaphore;  +	HANDLE semaphore;  #else -  sem_t semaphore; +	sem_t semaphore;  #endif  }; -Semaphore::Semaphore(const char *name) +Semaphore::Semaphore(std::size_t initial_count)  { -  this->name = name; -  //  DEBUG(semaphore, "Create [%s]\n", name); - -  prv = new struct semaphore_private_t(); +	prv = new struct semaphore_private_t();  #ifdef WIN32 -  prv->semaphore = CreateSemaphore(NULL,  // default security attributes -                                   0, // initial count -                                   std::numeric_limits<LONG>::max(), -                                   NULL); // unnamed semaphore +	prv->semaphore = CreateSemaphore(nullptr,  // default security attributes +	                                 initial_count, +	                                 std::numeric_limits<LONG>::max(), +	                                 nullptr); // unnamed semaphore  #else -  sem_init(&prv->semaphore, 0, 0); +	const int pshared = 0; +	sem_init(&prv->semaphore, pshared, initial_count);  #endif  }  Semaphore::~Semaphore()  { -  //  DEBUG(semaphore, "Delete [%s]\n", name); -  #ifdef WIN32 -  CloseHandle(prv->semaphore); +	CloseHandle(prv->semaphore);  #else -  sem_destroy(&prv->semaphore); +	sem_destroy(&prv->semaphore);  #endif -  delete prv; +	delete prv;  }  void Semaphore::post()  { -  //  DEBUG(semaphore, "Post [%s]\n", name); +#ifdef WIN32 +	ReleaseSemaphore(prv->semaphore, 1, NULL); +#else +	sem_post(&prv->semaphore); +#endif +} +bool Semaphore::wait(const std::chrono::milliseconds& timeout) +{  #ifdef WIN32 -  ReleaseSemaphore(prv->semaphore, 1, NULL); +	DWORD ret = WaitForSingleObject(prv->semaphore, timeout.count()); +	if(ret == WAIT_TIMEOUT) +	{ +		return false; +	} + +	assert(ret == WAIT_OBJECT_0);  #else -  sem_post(&prv->semaphore); +	struct timespec t = { +		// Whole seconds: +		(time_t)(timeout.count() % 1000), + +		// Remainder as nanoseconds: +		(long)((timeout.count() - (t.tv_sec * timeout.count())) * 1000000) +	}; + +	int ret = sem_timedwait(&prv->semaphore, &t); +	if(ret < 0) +	{ +		if(errno == ETIMEDOUT) +		{ +			return false; +		} + +		perror("sem_timedwait()"); +		assert(false); +	}  #endif + +	return true;  }  void Semaphore::wait()  { -  //  DEBUG(semaphore, "Wait [%s]\n", name); -  #ifdef WIN32 -  WaitForSingleObject(prv->semaphore, INFINITE); +	WaitForSingleObject(prv->semaphore, INFINITE);  #else -  sem_wait(&prv->semaphore); +	sem_wait(&prv->semaphore);  #endif  } - -#ifdef TEST_SEMAPHORE -//deps: -//cflags: -I.. $(PTHREAD_CFLAGS) -//libs: $(PTHREAD_LIBS) -#include <test.h> - -TEST_BEGIN; - -// TODO: Put some testcode here (see test.h for usable macros). -TEST_TRUE(false, "No tests yet!"); - -TEST_END; - -#endif/*TEST_SEMAPHORE*/ | 
