Всем привет!
Навеяно предыдущим топиком. Сначала еще раз покритикую код SergH
В конструкторе
m_write = write; //1
if (!m_write)
{
WaitForSingleObject(mutex, INFINITE); //2
между 1 и 2 может случиться переключение контекста, тогда будет жопа
В деструкторе я бы сначала проверил m_write и только потом вызывал бы
WaitForSingleObject(mutex, INFINITE);
Нет вызовов ClosaHandle().
Короче представляю вторую версию класса.
class Locker2
{
public:
Locker2()
{
mutex = CreateMutex(NULL, FALSE, NULL);
event = CreateEvent(NULL, TRUE, TRUE, NULL);
};
void Want2Write()
{
HANDLE h[] = {event, mutex};
WaitForMultipleObjects(2, h, TRUE, INFINITE);
m_write = true;
};
void Want2Read()
{
WaitForSingleObject(mutex, INFINITE);
m_write = false;
if (!readers)
SetEvent(event);
ReleaseMutex(mutex);
InterlockedDecrement(&readers);
};
void Done()
{
if (!m_write)
{
WaitForSingleObject(mutex, INFINITE);
if (!InterlockedDecrement(&readers))
SetEvent(event);
ReleaseMutex(mutex);
}
else
ReleaseMutex(mutex);
};
~Locker2()
{
CloseHandle(mutex);
CloseHandle(event);
};
LONG GetReaders(){return readers;};
private:
static HANDLE mutex;
static HANDLE event;
static LONG readers;
bool m_write;
};
HANDLE Locker2::mutex = NULL;
HANDLE Locker2::event = NULL;
LONG Locker2::readers = 0;
Критика принимается.