#include "Lock.hpp"
#include "EventLock.hpp"
#ifndef __SYNC
#define __SYNC
class Sync
{
private:
protected:
EventLock *lock;
EventLock *block;
public:
Sync();
void wait();
void notify();
};
#endif
==========================================
#include "EventLock.hpp"
#include "Sync.hpp"
Sync::Sync()
{
lock = new EventLock();
block = new EventLock();
}
void Sync::wait()
{
block->setState(EventLock::NON_SIGNALED);
lock->unlock();
block->lock();
lock->lock();
}
void Sync::notify()
{
block->setState(EventLock::SIGNALED);
}
===========================================
#include <windows.h>
#include "Lock.hpp"
#ifndef _EVENT_LOCK
#define _EVENT_LOCK
class EventLock : public Lock
{
private:
HANDLE event;
public:
const static int SIGNALED;
const static int NON_SIGNALED;
EventLock();
EventLock(const char* name);
virtual void lock();
void lock(HANDLE event);
virtual void unlock();
void unlock(HANDLE event);
void setState(int state);
HANDLE getEvent();
};
#endif
=====================================
#include <stdlib.h>
#include <stdio.h>
#include <windows.h>
#include "log.h"
#include "EventLock.hpp"
const int EventLock::SIGNALED = 1;
const int EventLock::NON_SIGNALED = 0;
EventLock::EventLock()
{
this->event = CreateEvent(NULL, FALSE, TRUE, NULL);
if (this->event == NULL)
{
DWORD error = GetLastError();
warn("create event error %d", error);
}
debug("EventLock()");
}
EventLock::EventLock(const char* name)
{
this->event = CreateEvent(NULL, FALSE, FALSE, name);
if (this->event == NULL)
{
DWORD error = GetLastError();
warn("create event error %d", error);
}
else
{
DWORD error = GetLastError();
if (error == ERROR_ALREADY_EXISTS)
{
debug("event name %s already exists, use the existed event instead.", name);
}
}
}
void EventLock::lock()
{
lock(this->event);
}
void EventLock::lock(HANDLE event)
{
DWORD e = WaitForSingleObject(event, INFINITE);
if (e == WAIT_FAILED)
{
DWORD error = GetLastError();
warn("wait error %d", error);
}
else if(e == WAIT_TIMEOUT)
{
debug("wait time out");
}
else if(e == WAIT_ABANDONED)
{
debug("wait abandoned");
}
}
void EventLock::unlock()
{
this->unlock(this->event);
}
void EventLock::unlock(HANDLE event)
{
BOOL isr = SetEvent(this->event);
if (! isr)
{
DWORD error = GetLastError();
warn("release event error %d", error);
}
}
void EventLock::setState(int state)
{
if (state == EventLock::SIGNALED)
{
int error = SetEvent(this->event);
if (! error)
{
DWORD e = GetLastError();
warn("error to set event object to signaled state");
}
}
else if(state == EventLock::NON_SIGNALED)
{
int error = ResetEvent(this->event);
if (! error)
{
DWORD e = GetLastError();
warn("error to set event object to nonsignaled state");
}
}
}
HANDLE EventLock::getEvent()
{
return this->event;
}
==========================================
#define _WIN32_WINNT 0x0400
#include <stdio.h>
#include <windows.h>
#include "../Sync.hpp"
#ifndef TEST_EVENT_LOCK_MESSAGE_DESTINATION
#define TEST_EVENT_LOCK_MESSAGE_DESTINATION
class TestEventLockMessageDestination : public Sync
{
private:
int i;
public:
TestEventLockMessageDestination()
{
i = 0;
}
void add()
{
lock->lock();
i++;
printf("[Producer] message %d\n", this->i);
if (i > 0)
{
this->notify();
}
lock->unlock();
}
void reduce()
{
lock->lock();
if (i <= 0)
{
this->wait();
}
i--;
printf("[Consumer] message %d\n", i);
lock->unlock();
}
};
#endif
========================================
#include <stdio.h>
#include "../Thread.hpp"
#include "TestEventLockMessageDestination.hpp"
#ifndef TEST_EVENT_LOCK_MESSAGE_CONSUMER
#define TEST_EVENT_LOCK_MESSAGE_CONSUMER
class TestEventLockMessageConsumer : public Thread
{
private:
TestEventLockMessageDestination *destination;
public:
TestEventLockMessageConsumer()
{
this->destination = NULL;
}
void registerConsumer(TestEventLockMessageDestination *destination)
{
this->destination = destination;
}
void run()
{
while (1)
{
if (destination != NULL)
{
this->destination->reduce();
}
//Sleep(500);
}
}
};
#endif
===================================================
#include <stdio.h>
#include "../Thread.hpp"
#include "TestEventLockMessageDestination.hpp"
#ifndef TEST_EVENT_LOCK_MESSAGE_PRODUCER
#define TEST_EVENT_LOCK_MESSAGE_PRODUCER
class TestEventLockMessageProducer : public Thread
{
private:
TestEventLockMessageDestination *destination;
public:
TestEventLockMessageProducer()
{
this->destination = NULL;
}
void registerProducer(TestEventLockMessageDestination *destination)
{
this->destination = destination;
}
void run()
{
while (1)
{
if (destination != NULL)
{
destination->add();
}
//Sleep(5000);
}
}
};
#endif
==========================================
#include "TestEventLockMessageDestination.hpp"
#include "TestEventLockMessageProducer.hpp"
#include "TestEventLockMessageConsumer.hpp"
void main()
{
///*
TestEventLockMessageDestination *destination = new TestEventLockMessageDestination();
TestEventLockMessageProducer *producer = new TestEventLockMessageProducer();
producer->registerProducer(destination);
producer->start();
TestEventLockMessageConsumer *consumer = new TestEventLockMessageConsumer();
consumer->registerConsumer(destination);
consumer->start();
ExitThread(0);
}