+Semaphore::Semaphore():
+ mutex(new Mutex),
+ own_mutex(true)
+{
+ init();
+}
+
+Semaphore::Semaphore(Mutex &m):
+ mutex(&m),
+ own_mutex(false)
+{
+ init();
+}
+
+void Semaphore::init()
+{
+#ifdef WIN32
+ count = 0;
+ sem = CreateSemaphore(0, 0, 32, 0);
+#else
+ pthread_cond_init(&sem, 0);
+#endif
+}
+
+Semaphore::~Semaphore()
+{
+ if(own_mutex)
+ delete mutex;
+#ifdef WIN32
+ CloseHandle(sem);
+#else
+ pthread_cond_destroy(&sem);
+#endif
+}
+
+#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
+