1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218
|
// Windows/Synchronization.h
#ifdef ENV_BEOS
#include <Locker.h>
#include <kernel/OS.h>
#include <list>
#endif
/* Remark : WFMO = WaitForMultipleObjects */
namespace NWindows { namespace NSynchronization { struct CBaseHandleWFMO; } }
typedef NWindows::NSynchronization::CBaseHandleWFMO *HANDLE;
DWORD WINAPI WaitForMultipleObjects( DWORD count, const HANDLE *handles, BOOL wait_all, DWORD timeout );
namespace NWindows {
namespace NSynchronization {
#ifdef ENV_BEOS
class CSynchro : BLocker, private Uncopyable
{
#define MAX_THREAD 256
thread_id _waiting[MAX_THREAD]; // std::list<thread_id> _waiting;
int index_waiting;
public:
CSynchro() { index_waiting = 0; }
void Create() { index_waiting = 0; }
~CSynchro() {}
void Enter() { Lock(); }
void Leave() { Unlock(); }
void WaitCond() {
_waiting[index_waiting++] = find_thread(NULL); // _waiting.push_back(find_thread(NULL));
thread_id sender;
Unlock();
int msg = receive_data(&sender, NULL, 0);
Lock();
}
void LeaveAndSignal() {
// Unlock();
// Lock();
// for (std::list<thread_id>::iterator index = _waiting.begin(); index != _waiting.end(); index++)
for(int index = 0 ; index < index_waiting ; index++)
{
send_data(_waiting[index], '7zCN', NULL, 0);
}
index_waiting = 0; // _waiting.clear();
Unlock();
}
};
#else // #ifdef ENV_BEOS
#ifdef DEBUG_SYNCHRO
class CSynchro: private Uncopyable
{
pthread_mutex_t _object;
pthread_cond_t _cond;
bool _isValid;
void dump_error(int ligne,int ret,const char *text,void *param);
public:
CSynchro();
~CSynchro();
void Create();
void Enter();
void Leave();
void WaitCond();
void LeaveAndSignal();
};
#else // #ifdef DEBUG_SYNCHRO
class CSynchro : private Uncopyable
{
pthread_mutex_t _object;
pthread_cond_t _cond;
bool _isValid;
public:
CSynchro() { _isValid = false; }
~CSynchro() {
if (_isValid) {
::pthread_mutex_destroy(&_object);
::pthread_cond_destroy(&_cond);
}
_isValid = false;
}
void Create() {
::pthread_mutex_init(&_object,0);
::pthread_cond_init(&_cond,0);
}
void Enter() {
::pthread_mutex_lock(&_object);
}
void Leave() {
::pthread_mutex_unlock(&_object);
}
void WaitCond() {
::pthread_cond_wait(&_cond, &_object);
}
void LeaveAndSignal() {
::pthread_cond_broadcast(&_cond);
::pthread_mutex_unlock(&_object);
}
};
#endif // #ifdef DEBUG_SYNCHRO
#endif // #ifdef ENV_BEOS
struct CBaseHandleWFMO // FIXME : private Uncopyable
{
CSynchro *_sync;
CBaseHandleWFMO() { }
operator HANDLE() { return this; }
virtual bool IsSignaledAndUpdate() = 0;
};
class CBaseEventWFMO : public CBaseHandleWFMO
{
bool _manual_reset;
bool _state;
public:
bool IsCreated() { return (this->_sync != 0); }
CBaseEventWFMO() { this->_sync = 0; }
~CBaseEventWFMO() { Close(); }
WRes Close() { this->_sync = 0; return S_OK; }
WRes Create(CSynchro *sync,bool manualReset, bool initiallyOwn)
{
this->_sync = sync;
this->_manual_reset = manualReset;
this->_state = initiallyOwn;
return S_OK;
}
WRes Set() {
this->_sync->Enter();
this->_state = true;
this->_sync->LeaveAndSignal();
return S_OK;
}
WRes Reset() {
this->_sync->Enter();
this->_state = false;
this->_sync->Leave();
return S_OK;
}
virtual bool IsSignaledAndUpdate() {
if (this->_state == true) {
if (this->_manual_reset == false) this->_state = false;
return true;
}
return false;
}
};
class CManualResetEventWFMO: public CBaseEventWFMO
{
public:
WRes Create(CSynchro *sync,bool initiallyOwn = false) { return CBaseEventWFMO::Create(sync,true, initiallyOwn); }
};
class CAutoResetEventWFMO: public CBaseEventWFMO
{
public:
WRes Create(CSynchro *sync) { return CBaseEventWFMO::Create(sync,false, false); }
WRes CreateIfNotCreated(CSynchro *sync)
{
if (IsCreated())
return 0;
return CBaseEventWFMO::Create(sync,false, false);
}
};
class CSemaphoreWFMO : public CBaseHandleWFMO
{
LONG _count;
LONG _maxCount;
public:
CSemaphoreWFMO() : _count(0), _maxCount(0) { this->_sync=0;}
WRes Create(CSynchro *sync,LONG initiallyCount, LONG maxCount)
{
if ((initiallyCount < 0) || (initiallyCount > maxCount) || (maxCount < 1)) return S_FALSE;
this->_sync = sync;
this->_count = initiallyCount;
this->_maxCount = maxCount;
return S_OK;
}
WRes Release(LONG releaseCount = 1) {
if (releaseCount < 1) return S_FALSE;
this->_sync->Enter();
LONG newCount = this->_count + releaseCount;
if (newCount > this->_maxCount)
{
this->_sync->Leave();
return S_FALSE;
}
this->_count = newCount;
this->_sync->LeaveAndSignal();
return S_OK;
}
WRes Close() { this->_sync=0; return S_OK; }
virtual bool IsSignaledAndUpdate() {
if (this->_count > 0) {
this->_count--;
return true;
}
return false;
}
};
}}
|