219 lines
4.9 KiB
C
219 lines
4.9 KiB
C
|
// 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;
|
||
|
}
|
||
|
};
|
||
|
|
||
|
}}
|
||
|
|