#include "protokit.h"
#ifdef UNIX
#include <unistd.h>
#endif
class SimpleThread
{
public:
SimpleThread();
~SimpleThread();
bool Start(ProtoEvent* parentEvent);
void Stop();
bool StartTimer()
{
bool result = dispatcher.SuspendThread();
if (result)
{
if (!timer.IsActive()) dispatcher.ActivateTimer(timer);
dispatcher.ResumeThread();
}
return result;
}
bool StopTimer()
{
bool result = dispatcher.SuspendThread();
{
if (timer.IsActive()) timer.Deactivate();
dispatcher.ResumeThread();
}
return result;
}
bool TimerIsActive()
{
bool result = dispatcher.SuspendThread();
if (result)
{
result = timer.IsActive();
dispatcher.ResumeThread();
}
return result;
}
bool SetEvent()
{
bool result = dispatcher.SuspendThread();
if (result)
{
result = event.Set();
dispatcher.ResumeThread();
}
return result;
}
private:
void OnTimeout(ProtoTimer& theTimer);
void OnEvent(ProtoEvent& theEvent);
ProtoDispatcher dispatcher;
ProtoTimer timer;
ProtoEvent event;
ProtoEvent* parent_event;
unsigned int timeout_count; };
SimpleThread::SimpleThread()
: event(true), parent_event(NULL), timeout_count(15)
{
timer.SetListener(this, &SimpleThread::OnTimeout);
timer.SetInterval(1.0);
timer.SetRepeat(-1);
event.SetNotifier(&dispatcher);
event.SetListener(this, &SimpleThread::OnEvent);
}
SimpleThread::~SimpleThread()
{
Stop();
}
bool SimpleThread::Start(ProtoEvent* parentEvent)
{
if (!event.Open())
{
PLOG(PL_ERROR, "eventExample: SimpleThread::Start() event open failure ...\n");
return false;
}
dispatcher.ActivateTimer(timer);
if (dispatcher.StartThread())
{
parent_event = parentEvent;
return true;
}
else
{
PLOG(PL_ERROR, "eventExample: SimpleThread::Start() thread start failure ...\n");
timer.Deactivate();
event.Close();
return false;
}
}
void SimpleThread::Stop()
{
dispatcher.Stop();
if (timer.IsActive()) timer.Deactivate();
event.Close();
}
void SimpleThread::OnTimeout(ProtoTimer& theTimer)
{
TRACE("eventExample: child thread SimpleThread::OnTimeout() timeout_count:%d ...\n", timeout_count);
if ((1 == timeout_count) && (NULL != parent_event))
{
TRACE("eventExample: child thread signaling main thread ...\n");
parent_event->Set();
}
if (0 != timeout_count)
timeout_count--;
}
void SimpleThread::OnEvent(ProtoEvent& theEvent)
{
TRACE("eventExample: child thread SimpleThread::OnEvent() ...\n");
}
int main(int argc, char* argv[])
{
SimpleThread simpleThread;
ProtoEvent myEvent(false);
if (!myEvent.Open())
{
PLOG(PL_ERROR, "eventExample:myEvent.Open() error:%s\n", GetErrorString());
return -1;
}
if (!simpleThread.Start(&myEvent))
{
PLOG(PL_ERROR, "eventExample: SimpleThread::Start() error\n");
return -1;
}
int count = 2;
while (count--)
{
#ifdef WIN32
Sleep(3000);
#else
sleep(3);
#endif TRACE("eventExample: main thread countdown = %d\n",count);
if (0 == count)
{
TRACE("eventExample: main thread waiting for event signal from child ...\n");
myEvent.Wait();
TRACE("eventExample: main thread got event signal from child ...\n");
simpleThread.Stop();
}
if (1 == count)
{
TRACE("eventExample: main thread signaling child thread ...\n");
simpleThread.SetEvent();
}
}
TRACE("eventExample: main thread simpleThread stopped.\n");
TRACE("eventExample: main thread Done.\n");
return 0;
}