/*
* Thread that support cross platform and support global and local start routine, and support
* Windows api and C Run-Time Library(even extension) on windows.
* <p>
* To implements a simple thread, only to overrides the run method.
*
* @author ada
* @version 1.0
* @since 1.0
*/
#include <windows.h>
#include "Runnable.hpp"
#if ! defined THREAD
#define THREAD
// GLOBAL_START_ROUTINE is a user defined macro, likes a switch, to determine whether to
// select global thread start routine or not. GLOBAL_START_ROUTINE can be defined in program,
// or using compiler preprocessor options(PREPROCESSOR) /D to define user defined macro
// GLOBAL_START_ROUTINE to compiles global start routine edition of Thread
#if defined GLOBAL_START_ROUTINE
#define _GLOBAL_START_ROUTINE
#pragma message ("GLOBAL_START_ROUTINE defined, using global thread start routine.")
// using compiler linking options /MT to compiles C Run-Time Library(_beginthread, _beginthreadex)
// edition of Thread
#if defined(_MT) && (! defined(_MT_RT_EX))
#pragma message ("Using C Run-Time Library global thread start routine.")
//#error "C Run-Time Library global thread start routine not supported."
void execute(void *args);
#elif defined(_MT) && defined(_MT_RT_EX)
#pragma message ("Using C Run-Time Library extension global thread start routine.")
//#error "C Run-Time Library extension global thread start routine not supported."
unsigned __stdcall execute(void *arg);
#else
DWORD execute(LPVOID args);
#endif
#else
#pragma message ("GLOBAL_START_ROUTINE not defined, do not using global thread start routine.")
// If GLOBAL_START_ROUTINE not defined, for thread start routine function details, See Thread class
// declaration when user defined macro defined
#endif
/**
*
*
*
*/
class /*TK_API*/ Thread : public Runnable
{
private:
DWORD threadID;
Runnable *target;
public:
Thread();
Thread(const Runnable *runnable);
#if ! defined _GLOBAL_START_ROUTINE
#if defined(_MT) && (! defined(_MT_RT_EX))
#pragma message ("Using C Run-Time Library global thread start routine.")
#error "C Run-Time Library global thread start routine not supported."
#elif defined(_MT) && defined(_MT_RT_EX)
#pragma message ("Using C Run-Time Library extension global thread start routine.")
#error "C Run-Time Library extension global thread start routine not supported."
#else
static DWORD execute(LPVOID args);
#endif
#endif
void start();
virtual void run();
};
#endif
======================================================================
/*
*
*
* @AUTHOR ADA
* @VERSION 1.0
* @SINCE 1.0
*/
#include <stdio.h>
#include <stdlib.h>
#include <string>
#include <windows.h>
#include <log.h>
#include "Thread.hpp"
//#define _MT
using namespace std;
#if ! defined _GLOBAL_START_ROUTINE
DWORD Thread::execute(LPVOID args)
{
Thread* t = (Thread *) args;
t->run();
return 1;
}
#else
#if defined(_MT) && (! defined(_MT_RT_EX))
void execute(void *args)
{
Thread* t = (Thread *) args;
t->run();
}
#elif defined(_MT) && defined(_MT_RT_EX)
unsigned __stdcall execute(void *arg)
{
Thread* t = (Thread *) args;
t->run();
return 0;
}
#else
DWORD execute(LPVOID args)
{
Thread* t = (Thread *) args;
t->run();
return 1;
}
#endif
#endif
/**
*
*
*
*/
Thread::Thread()
{
this->threadID = 0;
this->target = NULL;
}
Thread::Thread(const Runnable *runnable)
{
this->threadID = 0;
this->target = (Runnable *) runnable;
}
void Thread::start()
{
#ifndef _GLOBAL_START_ROUTINE
LPTHREAD_START_ROUTINE startRoutine = (LPTHREAD_START_ROUTINE) Thread::execute;
printf("GLOBAL_START_ROUTINE not defined, do not using global thread start routine\n");
#else
LPTHREAD_START_ROUTINE startRoutine = (LPTHREAD_START_ROUTINE) execute;
printf("GLOBAL_START_ROUTINE defined, using global thread start routine\n");
#endif
::CreateThread(NULL, 0, startRoutine, (LPVOID) this, 0, &(this->threadID));
debug("Thread %d started", this->threadID);
}
void Thread::run()
{
if (target != NULL)
{
target->run();
}
else
{
debug("Thread::run()");
}
}
================================================================================
#ifndef _MT
#error "Compiler linking options /MT not specific"
#endif
#include <stdio.h>
#include <windows.h>
#include <process.h>
#include "../Thread.hpp"
#include "../LinkedLibrary.h"
void start_address(void *arg)
{
printf("_beginthread start_address\n");
}
unsigned __stdcall start_address_ex(void *arg)
{
printf("_beginthreadex start_address_ex\n");
return 0;
}
int main()
{
printf("Thread test\n");
#ifdef _MT
printf("MT defined\n");
#endif
unsigned long th;
printf("Thread _beginthread test\n");
th = _beginthread(start_address,
0,
NULL);
printf("_beginthread return %ld\n", th);
unsigned thread;
// CREATE_SUSPENDED
th = _beginthreadex(NULL, 0, start_address_ex, NULL, 0, &thread);
Thread *t = new Thread();
t->start();
ExitThread(0);
return 0;
}
===================================================================
DEBUG=../Debug
PATH_VS=D:\usr\bin\Microsoft Visual Studio\VC98
CL="$(PATH_VS)\Bin\cl.exe"
LINK="$(PATH_VS)\Bin\link.exe"
INCLUDE="D:\usr\bin\Microsoft Visual Studio\VC98\Include"
LIB="D:\usr\bin\Microsoft Visual Studio\VC98\Lib"
INCLUDE_LIB_LOG=D:\home\admin\workstation\c\liblog
LIB_LIB_LOG=D:\home\admin\workstation\c\liblog\Debug
INCLUDE_MYSQL=D:\usr\srv\mysql51\include
LIB_MYSQL=D:\usr\srv\mysql51\lib\debug
INCLUDE_LUA=D:\usr\bin\Lua\5.1\include
LIB_LUA=D:\usr\bin\Lua\5.1\lib
liblog.lib: clean
# using compiler linking options /MT, If compiles _beginthread edition of Thread
$(CL) /GX /W3 /MT /DGLOBAL_START_ROUTINE /I $(INCLUDE) /I $(INCLUDE_LIB_LOG) /c /Fo$(DEBUG)/ ../Thread.cpp
$(CL) /GX /W3 /MT /DGLOBAL_START_ROUTINE /I $(INCLUDE) /c /Fo$(DEBUG)/ ThreadTest__beginthread.cpp
$(LINK) /LIBPATH:$(LIB) /LIBPATH:$(LIB_LIB_LOG) /LIBPATH:$(LIB_MYSQL) /LIBPATH:$(LIB_LUA) /OUT:$(DEBUG)/ThreadTest__beginthread.exe $(DEBUG)/*.obj
cp ../liblog.dll $(DEBUG)
clean:
rm -Rf ./*.bak
rm -Rf ./*.o
rm -Rf ./*.obj
rm -Rf ./*.exe
rm -Rf ../Debug/*