From fb7bb2ee352cf83a7596a7ed7ba2913a2257e540 Mon Sep 17 00:00:00 2001 From: Bent Bisballe Nyeng Date: Wed, 13 Apr 2016 18:30:56 +0200 Subject: New Semaphore method wait with timeout. --- drumgizmo/output/jackaudio.cc | 1 - src/drumkitloader.cc | 3 +- src/semaphore.cc | 96 +++++++++++++++++++++++++------------------ src/semaphore.h | 24 ++++++----- 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 - #include +#include #ifdef WIN32 #include #else -// Make sure we don't include /this/ file... +// Make sure we don't include /this/ files header... #include <../include/semaphore.h> +#include +#include #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::max(), - NULL); // unnamed semaphore + prv->semaphore = CreateSemaphore(nullptr, // default security attributes + initial_count, + std::numeric_limits::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_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 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__*/ -- cgit v1.2.3