| // 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; |
| } |
| }; |
| |
| }} |
| |