mame/3rdparty/lzma/CPP/Windows/Synchronization.h

394 lines
8.5 KiB
C++

// Windows/Synchronization.h
#ifndef __WINDOWS_SYNCHRONIZATION_H
#define __WINDOWS_SYNCHRONIZATION_H
#include "../../C/Threads.h"
#include "../Common/MyTypes.h"
#include "Defs.h"
#ifdef _WIN32
#include "Handle.h"
#endif
namespace NWindows {
namespace NSynchronization {
class CBaseEvent MY_UNCOPYABLE
{
protected:
::CEvent _object;
public:
bool IsCreated() { return Event_IsCreated(&_object) != 0; }
CBaseEvent() { Event_Construct(&_object); }
~CBaseEvent() { Close(); }
WRes Close() { return Event_Close(&_object); }
#ifdef _WIN32
operator HANDLE() { return _object; }
WRes Create(bool manualReset, bool initiallyOwn, LPCTSTR name = NULL, LPSECURITY_ATTRIBUTES sa = NULL)
{
_object = ::CreateEvent(sa, BoolToBOOL(manualReset), BoolToBOOL(initiallyOwn), name);
if (name == NULL && _object != 0)
return 0;
return ::GetLastError();
}
WRes Open(DWORD desiredAccess, bool inheritHandle, LPCTSTR name)
{
_object = ::OpenEvent(desiredAccess, BoolToBOOL(inheritHandle), name);
if (_object != 0)
return 0;
return ::GetLastError();
}
#endif
WRes Set() { return Event_Set(&_object); }
// bool Pulse() { return BOOLToBool(::PulseEvent(_handle)); }
WRes Reset() { return Event_Reset(&_object); }
WRes Lock() { return Event_Wait(&_object); }
};
class CManualResetEvent: public CBaseEvent
{
public:
WRes Create(bool initiallyOwn = false)
{
return ManualResetEvent_Create(&_object, initiallyOwn ? 1: 0);
}
WRes CreateIfNotCreated_Reset()
{
if (IsCreated())
return Reset();
return ManualResetEvent_CreateNotSignaled(&_object);
}
#ifdef _WIN32
WRes CreateWithName(bool initiallyOwn, LPCTSTR name)
{
return CBaseEvent::Create(true, initiallyOwn, name);
}
#endif
};
class CAutoResetEvent: public CBaseEvent
{
public:
WRes Create()
{
return AutoResetEvent_CreateNotSignaled(&_object);
}
WRes CreateIfNotCreated_Reset()
{
if (IsCreated())
return Reset();
return AutoResetEvent_CreateNotSignaled(&_object);
}
};
/*
#ifdef _WIN32
class CObject: public CHandle
{
public:
WRes Lock(DWORD timeoutInterval = INFINITE)
{ return (::WaitForSingleObject(_handle, timeoutInterval) == WAIT_OBJECT_0 ? 0 : ::GetLastError()); }
};
class CMutex: public CObject
{
public:
WRes Create(bool initiallyOwn, LPCTSTR name = NULL, LPSECURITY_ATTRIBUTES sa = NULL)
{
_handle = ::CreateMutex(sa, BoolToBOOL(initiallyOwn), name);
if (name == NULL && _handle != 0)
return 0;
return ::GetLastError();
}
#ifndef UNDER_CE
WRes Open(DWORD desiredAccess, bool inheritHandle, LPCTSTR name)
{
_handle = ::OpenMutex(desiredAccess, BoolToBOOL(inheritHandle), name);
if (_handle != 0)
return 0;
return ::GetLastError();
}
#endif
WRes Release()
{
return ::ReleaseMutex(_handle) ? 0 : ::GetLastError();
}
};
class CMutexLock MY_UNCOPYABLE
{
CMutex *_object;
public:
CMutexLock(CMutex &object): _object(&object) { _object->Lock(); }
~CMutexLock() { _object->Release(); }
};
#endif // _WIN32
*/
class CSemaphore MY_UNCOPYABLE
{
::CSemaphore _object;
public:
CSemaphore() { Semaphore_Construct(&_object); }
~CSemaphore() { Close(); }
WRes Close() { return Semaphore_Close(&_object); }
#ifdef _WIN32
operator HANDLE() { return _object; }
#endif
// bool IsCreated() const { return Semaphore_IsCreated(&_object) != 0; }
WRes Create(UInt32 initCount, UInt32 maxCount)
{
return Semaphore_Create(&_object, initCount, maxCount);
}
WRes OptCreateInit(UInt32 initCount, UInt32 maxCount)
{
return Semaphore_OptCreateInit(&_object, initCount, maxCount);
}
WRes Release() { return Semaphore_Release1(&_object); }
WRes Release(UInt32 releaseCount) { return Semaphore_ReleaseN(&_object, releaseCount); }
WRes Lock() { return Semaphore_Wait(&_object); }
};
class CCriticalSection MY_UNCOPYABLE
{
::CCriticalSection _object;
public:
CCriticalSection() { CriticalSection_Init(&_object); }
~CCriticalSection() { CriticalSection_Delete(&_object); }
void Enter() { CriticalSection_Enter(&_object); }
void Leave() { CriticalSection_Leave(&_object); }
};
class CCriticalSectionLock MY_UNCOPYABLE
{
CCriticalSection *_object;
void Unlock() { _object->Leave(); }
public:
CCriticalSectionLock(CCriticalSection &object): _object(&object) {_object->Enter(); }
~CCriticalSectionLock() { Unlock(); }
};
#ifdef _WIN32
typedef HANDLE CHandle_WFMO;
typedef CSemaphore CSemaphore_WFMO;
typedef CAutoResetEvent CAutoResetEvent_WFMO;
typedef CManualResetEvent CManualResetEvent_WFMO;
inline DWORD WINAPI WaitForMultiObj_Any_Infinite(DWORD count, const CHandle_WFMO *handles)
{
return ::WaitForMultipleObjects(count, handles, FALSE, INFINITE);
}
#define SYNC_OBJ_DECL(obj)
#define SYNC_WFMO(x)
#define SYNC_PARAM(x)
#define SYNC_PARAM_DECL(x)
#else // _WIN32
// POSIX sync objects for WaitForMultipleObjects
#define SYNC_WFMO(x) x
#define SYNC_PARAM(x) x,
#define SYNC_PARAM_DECL(x) NWindows::NSynchronization::CSynchro *x
#define SYNC_OBJ_DECL(x) NWindows::NSynchronization::CSynchro x;
class CSynchro MY_UNCOPYABLE
{
pthread_mutex_t _mutex;
pthread_cond_t _cond;
bool _isValid;
public:
CSynchro() { _isValid = false; }
~CSynchro()
{
if (_isValid)
{
::pthread_mutex_destroy(&_mutex);
::pthread_cond_destroy(&_cond);
}
_isValid = false;
}
WRes Create()
{
RINOK(::pthread_mutex_init(&_mutex, 0));
WRes ret = ::pthread_cond_init(&_cond, 0);
_isValid = 1;
return ret;
}
WRes Enter()
{
return ::pthread_mutex_lock(&_mutex);
}
WRes Leave()
{
return ::pthread_mutex_unlock(&_mutex);
}
WRes WaitCond()
{
return ::pthread_cond_wait(&_cond, &_mutex);
}
WRes LeaveAndSignal()
{
WRes res1 = ::pthread_cond_broadcast(&_cond);
WRes res2 = ::pthread_mutex_unlock(&_mutex);
return (res2 ? res2 : res1);
}
};
struct CBaseHandle_WFMO;
typedef NWindows::NSynchronization::CBaseHandle_WFMO *CHandle_WFMO;
// these constants are from Windows
#define WAIT_OBJECT_0 0
#define WAIT_FAILED ((DWORD)0xFFFFFFFF)
DWORD WINAPI WaitForMultiObj_Any_Infinite(DWORD count, const CHandle_WFMO *handles);
struct CBaseHandle_WFMO MY_UNCOPYABLE
{
CSynchro *_sync;
CBaseHandle_WFMO(): _sync(NULL) {}
operator CHandle_WFMO() { return this; }
virtual bool IsSignaledAndUpdate() = 0;
};
class CBaseEvent_WFMO : public CBaseHandle_WFMO
{
bool _manual_reset;
bool _state;
public:
// bool IsCreated() { return (this->_sync != NULL); }
// CBaseEvent_WFMO() { ; }
~CBaseEvent_WFMO() { Close(); }
WRes Close() { this->_sync = NULL; return 0; }
WRes Create(
CSynchro *sync,
bool manualReset, bool initiallyOwn)
{
this->_sync = sync;
this->_manual_reset = manualReset;
this->_state = initiallyOwn;
return 0;
}
WRes Set()
{
RINOK(this->_sync->Enter());
this->_state = true;
return this->_sync->LeaveAndSignal();
}
WRes Reset()
{
RINOK(this->_sync->Enter());
this->_state = false;
return this->_sync->Leave();
}
virtual bool IsSignaledAndUpdate()
{
if (this->_state == false)
return false;
if (this->_manual_reset == false)
this->_state = false;
return true;
}
};
class CManualResetEvent_WFMO: public CBaseEvent_WFMO
{
public:
WRes Create(CSynchro *sync, bool initiallyOwn = false) { return CBaseEvent_WFMO::Create(sync, true, initiallyOwn); }
};
class CAutoResetEvent_WFMO: public CBaseEvent_WFMO
{
public:
WRes Create(CSynchro *sync) { return CBaseEvent_WFMO::Create(sync, false, false); }
WRes CreateIfNotCreated_Reset(CSynchro *sync)
{
return Create(sync);
}
};
class CSemaphore_WFMO : public CBaseHandle_WFMO
{
UInt32 _count;
UInt32 _maxCount;
public:
CSemaphore_WFMO() : _count(0), _maxCount(0) {}
WRes Close() { this->_sync = NULL; return 0; }
WRes Create(CSynchro *sync, UInt32 initCount, UInt32 maxCount)
{
if (initCount > maxCount || maxCount < 1)
return EINVAL;
this->_sync = sync;
this->_count = initCount;
this->_maxCount = maxCount;
return 0;
}
WRes Release(UInt32 releaseCount = 1)
{
if (releaseCount < 1)
return EINVAL;
RINOK(this->_sync->Enter());
UInt32 newCount = this->_count + releaseCount;
if (newCount > this->_maxCount)
{
RINOK(this->_sync->Leave());
return ERROR_TOO_MANY_POSTS; // EINVAL
}
this->_count = newCount;
return this->_sync->LeaveAndSignal();
}
virtual bool IsSignaledAndUpdate()
{
if (this->_count == 0)
return false;
this->_count--;
return true;
}
};
#endif // _WIN32
}}
#endif