summaryrefslogtreecommitdiff
path: root/src/semaphore.cc
diff options
context:
space:
mode:
authorBent Bisballe Nyeng <deva@aasimon.org>2016-04-13 18:30:56 +0200
committerBent Bisballe Nyeng <deva@aasimon.org>2016-04-13 18:30:56 +0200
commitfb7bb2ee352cf83a7596a7ed7ba2913a2257e540 (patch)
tree7f45c45563dd13233061d25a96967c4b1e9958c5 /src/semaphore.cc
parent057ef1d83ba263fb2adf1aa86f8e281ab0065c43 (diff)
New Semaphore method wait with timeout.
Diffstat (limited to 'src/semaphore.cc')
-rw-r--r--src/semaphore.cc96
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*/