]> git.tdb.fi Git - libs/core.git/blobdiff - source/core/semaphore.cpp
Assimilate exceptions and RefPtr from mspmisc
[libs/core.git] / source / core / semaphore.cpp
index 9107a763aa0416e111d47390ffecda7cc0163c77..b9e7080cb04ea2b6e4808de5de658f1400322708 100644 (file)
@@ -1,4 +1,5 @@
-/*
+/* $Id$
+
 This file is part of libmspcore
 Copyright © 2006  Mikko Rasa, Mikkosoft Productions
 Distributed under the LGPL
@@ -12,6 +13,63 @@ Distributed under the LGPL
 
 namespace Msp {
 
+Semaphore::Semaphore():
+       mutex(new Mutex),
+       own_mutex(true)
+{
+       init();
+}
+
+Semaphore::Semaphore(Mutex &m):
+       mutex(&m),
+       own_mutex(false)
+{
+       init();
+}
+
+#ifdef WIN32
+int Semaphore::signal()
+{
+       if(count==0) 
+               return 0;
+
+       int ret=!ReleaseSemaphore(sem, 1, 0); 
+
+       unsigned old_count=count;
+       mutex->unlock();
+       while(count==old_count)
+               Sleep(0);
+       mutex->lock();
+
+       return ret;
+}
+
+int Semaphore::broadcast()
+{
+       if(count==0)
+               return 0;
+       int ret=!ReleaseSemaphore(sem, count, 0);
+
+       mutex->unlock();
+       while(count)
+               Sleep(0);
+       mutex->lock();
+
+       return ret;
+}
+
+int Semaphore::wait()
+{ 
+       ++count; 
+       mutex->unlock();
+       DWORD ret=WaitForSingleObject(sem, INFINITE); 
+       mutex->lock();
+       --count;
+       
+       return ret==WAIT_OBJECT_0;
+}
+#endif
+
 int Semaphore::wait(const Time::TimeDelta &d)
 {
 #ifndef WIN32
@@ -21,15 +79,40 @@ int Semaphore::wait(const Time::TimeDelta &d)
        timeout.tv_sec=ts.raw()/1000000;
        timeout.tv_nsec=(ts.raw()%1000000)*1000;
 
-       MutexLock l(mutex);
-       int r=pthread_cond_timedwait(&sem, &mutex.mutex, &timeout);
+       int r=pthread_cond_timedwait(&sem, &mutex->mutex, &timeout);
        if(r==ETIMEDOUT)
                return 1;
        else if(r)
                return -1;
        return 0;
 #else
-       return WaitForSingleObject(sem, (DWORD)(d/Time::usec))==WAIT_OBJECT_0;
+       ++count;
+       mutex->lock();
+       DWORD ret=WaitForSingleObject(sem, (DWORD)(d/Time::usec));
+       mutex->unlock();
+       --count;
+       return ret==WAIT_OBJECT_0;
+#endif
+}
+
+Semaphore::~Semaphore()
+{
+       if(own_mutex)
+               delete mutex;
+#ifdef WIN32
+       CloseHandle(sem);
+#else
+       pthread_cond_destroy(&sem);
+#endif
+}
+
+void Semaphore::init()
+{
+#ifdef WIN32
+       count=0;
+       sem=CreateSemaphore(0, 0, 32, 0);
+#else
+       pthread_cond_init(&sem, 0);
 #endif
 }