// Common, groups WinWrap, Thread
// Copyright Alexander Liss
#include <process.h>
#include "thread.h"
// Thread
void Thread::selfdestruct()
{
// this order !
destruct=true;
loop_sleep=0;
wake_up();
}
// AsyncStep
int AsyncStep::loop(bool& continue_loop)
{
continue_loop=true;
int g=respond();
if(g) return g;
wait(thread_event);
return 0;
}
// ThreadControl
// creates the thread, which begins executing using the Thread OBJECT
int ThreadControl::launch( Thread& cThread,
unsigned uInitFlag,
LPSECURITY_ATTRIBUTES lpSecurity,
unsigned uStackSize)
{
thread_object=&cThread;
if(! thread_object)
{
status = 1;
return 1;
}
handle = (HANDLE) _beginthreadex( lpSecurity, uStackSize, thread_procedure, thread_object, uInitFlag, &thread_id);
if (is_valid_handle(handle))
{
status = NO_ERROR; // 0
}
else
{
status = errno;
return 2;
}
return 0;
}
unsigned _stdcall ThreadControl::thread_procedure(void *pThread)
{
int hr1=0,hr2=0,hr3=0,hr4=0;
bool loop=true;
Thread *p_thread = static_cast<Thread *>(pThread);
if(p_thread->destruct)
{
_endthreadex(0);
return destructed;
}
hr1=p_thread->startup();
if(! hr1)
while(loop)
{
if(p_thread->destruct)
{
hr2=1;
break;
}
hr3=p_thread->loop(loop);
if(hr3) break;
if(p_thread->destruct)
{
hr2=1;
break;
}
if(p_thread->loop_sleep>0)
wait(p_thread->thread_event,p_thread->loop_sleep);
//Sleep(p_thread->loop_sleep);
}
hr4=p_thread->cleanup();
unsigned hr=0;
if(hr1) hr=failed_startup;
else if(hr2) hr=destructed;
else if(hr3) hr=bad_loop;
else if(hr4) hr=failed_cleanup;
_endthreadex(hr);
return hr;
}
// suspend the thread
DWORD ThreadControl::suspend()
{
if(! thread_object)
return 0xFFFFFFFF;
return ::SuspendThread( handle);
}
// resume the thread
DWORD ThreadControl::resume()
{
if(! thread_object)
return 0xFFFFFFFF;
return ::ResumeThread( handle);
}
// terminate the thread
BOOL ThreadControl::terminate( DWORD dwExitCode)
{
if(! thread_object)
return FALSE;
return ::TerminateThread( handle, dwExitCode);
}
// read a thread's exit code
BOOL ThreadControl::get_exit_code( DWORD *pdwExitCode)
{
if(! thread_object)
return FALSE;
return ::GetExitCodeThread( handle, pdwExitCode);
}
// set a thread's priority
BOOL ThreadControl::set_priority( int nPriority)
{
if(! thread_object)
return FALSE;
return ::SetThreadPriority( handle, nPriority);
}
// read a thread's priority
int ThreadControl::get_priority()
{
if(! thread_object)
return 0;
return ::GetThreadPriority( handle);
}
// return the thread's identifier
DWORD ThreadControl::get_thread_id()const
{
if(! thread_object)
return 0;
return static_cast<DWORD>(thread_id);
}
#if(_WIN32_WINNT >= 0x0400)
DWORD ThreadControl::queue_APC(PAPCFUNC pfnAPC,DWORD dwData)
{
if(! thread_object || !handle)
return 0;
return ::QueueUserAPC(pfnAPC,handle,dwData);
}
#endif