summaryrefslogtreecommitdiff
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
parent057ef1d83ba263fb2adf1aa86f8e281ab0065c43 (diff)
New Semaphore method wait with timeout.
-rw-r--r--drumgizmo/output/jackaudio.cc1
-rw-r--r--src/drumkitloader.cc3
-rw-r--r--src/semaphore.cc96
-rw-r--r--src/semaphore.h24
4 files changed, 70 insertions, 54 deletions
diff --git a/drumgizmo/output/jackaudio.cc b/drumgizmo/output/jackaudio.cc
index 7710e14..abd7d4f 100644
--- a/drumgizmo/output/jackaudio.cc
+++ b/drumgizmo/output/jackaudio.cc
@@ -33,7 +33,6 @@ JackAudioOutputEngine::JackAudioOutputEngine(JackClient& client)
: AudioOutputEngine{}
, client(client)
, channels{}
- , sema{"jackaudio"}
{
client.add(*this);
}
diff --git a/src/drumkitloader.cc b/src/drumkitloader.cc
index f9e45db..d785bc4 100644
--- a/src/drumkitloader.cc
+++ b/src/drumkitloader.cc
@@ -32,8 +32,7 @@
#include "drumgizmo.h"
DrumKitLoader::DrumKitLoader(Settings& settings)
- : semaphore("drumkitloader")
- , framesize(0)
+ : framesize(0)
, settings(settings)
{
run();
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*/
diff --git a/src/semaphore.h b/src/semaphore.h
index 4464898..d5995cb 100644
--- a/src/semaphore.h
+++ b/src/semaphore.h
@@ -24,22 +24,26 @@
* along with DrumGizmo; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-#ifndef __PRACRO_SEMAPHORE_H__
-#define __PRACRO_SEMAPHORE_H__
+#pragma once
+
+#include <chrono>
struct semaphore_private_t;
-class Semaphore {
+class Semaphore
+{
public:
- Semaphore(const char *name = "");
- ~Semaphore();
+ Semaphore(std::size_t initial_count = 0);
+ ~Semaphore();
+
+ void post();
- void post();
- void wait();
+ //! Lock semaphore with timeout.
+ //! \returns true if the semaphore was locked, false on timeout.
+ bool wait(const std::chrono::milliseconds& timeout);
+
+ void wait();
private:
struct semaphore_private_t *prv{nullptr};
- const char *name{nullptr};
};
-
-#endif/*__PRACRO_SEMAPHORE_H__*/