]> git.tdb.fi Git - libs/core.git/blob - source/core/semaphore.cpp
MSVC compatibility fixes
[libs/core.git] / source / core / semaphore.cpp
1 /* $Id$
2
3 This file is part of libmspcore
4 Copyright © 2006  Mikko Rasa, Mikkosoft Productions
5 Distributed under the LGPL
6 */
7 #ifndef WIN32
8 #include <sys/time.h>
9 #endif
10 #include <errno.h>
11 #include "semaphore.h"
12 #include "../time/timestamp.h"
13 #include "../time/units.h"
14 #include "../time/utils.h"
15
16 namespace Msp {
17
18 Semaphore::Semaphore():
19         mutex(new Mutex),
20         own_mutex(true)
21 {
22         init();
23 }
24
25 Semaphore::Semaphore(Mutex &m):
26         mutex(&m),
27         own_mutex(false)
28 {
29         init();
30 }
31
32 #ifdef WIN32
33 int Semaphore::signal()
34 {
35         if(count==0) 
36                 return 0;
37
38         int ret=!ReleaseSemaphore(sem, 1, 0); 
39
40         unsigned old_count=count;
41         mutex->unlock();
42         while(count==old_count)
43                 Sleep(0);
44         mutex->lock();
45
46         return ret;
47 }
48
49 int Semaphore::broadcast()
50 {
51         if(count==0)
52                 return 0;
53         int ret=!ReleaseSemaphore(sem, count, 0);
54
55         mutex->unlock();
56         while(count)
57                 Sleep(0);
58         mutex->lock();
59
60         return ret;
61 }
62
63 int Semaphore::wait()
64
65         ++count; 
66         mutex->unlock();
67         DWORD ret=WaitForSingleObject(sem, INFINITE); 
68         mutex->lock();
69         --count;
70         
71         return ret==WAIT_OBJECT_0;
72 }
73 #endif
74
75 int Semaphore::wait(const Time::TimeDelta &d)
76 {
77 #ifndef WIN32
78         Time::TimeStamp ts=Time::now()+d;
79
80         timespec timeout;
81         timeout.tv_sec=ts.raw()/1000000;
82         timeout.tv_nsec=(ts.raw()%1000000)*1000;
83
84         int r=pthread_cond_timedwait(&sem, &mutex->mutex, &timeout);
85         if(r==ETIMEDOUT)
86                 return 1;
87         else if(r)
88                 return -1;
89         return 0;
90 #else
91         ++count;
92         mutex->lock();
93         DWORD ret=WaitForSingleObject(sem, (DWORD)(d/Time::usec));
94         mutex->unlock();
95         --count;
96         return ret==WAIT_OBJECT_0;
97 #endif
98 }
99
100 Semaphore::~Semaphore()
101 {
102         if(own_mutex)
103                 delete mutex;
104 #ifdef WIN32
105         CloseHandle(sem);
106 #else
107         pthread_cond_destroy(&sem);
108 #endif
109 }
110
111 void Semaphore::init()
112 {
113 #ifdef WIN32
114         count=0;
115         sem=CreateSemaphore(0, 0, 32, 0);
116 #else
117         pthread_cond_init(&sem, 0);
118 #endif
119 }
120
121 } // namespace Msp