// Windows/Synchronization.h #ifdef ENV_BEOS #include #include #include #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 _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::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; } }; }}