This commit is contained in:
2024-08-07 09:16:27 -04:00
parent fdfadd5c7e
commit 5f971cf684
5200 changed files with 731717 additions and 0 deletions

507
thread/CONTEXT.HPP Normal file
View File

@@ -0,0 +1,507 @@
#ifndef _THREAD_CONTEXT_HPP_
#define _THREAD_CONTEXT_HPP_
#include <stdio.h>
#ifndef _COMMON_STRING_HPP_
#include <common/string.hpp>
#endif
#ifndef _THREAD_FLOATINGSAVEAREA_HPP_
#include <thread/savearea.hpp>
#endif
class Context : private CONTEXT
{
public:
enum ContextType{FloatingPoint=CONTEXT_FLOATING_POINT,Integer=CONTEXT_INTEGER,
Control=CONTEXT_CONTROL,Segments=CONTEXT_SEGMENTS,Full=CONTEXT_FULL,
DebugRegisters=CONTEXT_DEBUG_REGISTERS};
Context(void);
Context(const Context &someContext);
Context(const CONTEXT &someCONTEXT);
virtual ~Context(void);
Context &operator=(const Context &someContext);
Context &operator=(const CONTEXT &someCONTEXT);
WORD operator==(const Context &someContext)const;
WORD operator==(const CONTEXT &someCONTEXT)const;
operator String(void)const;
WORD getThreadContext(HANDLE hThread);
WORD setThreadContext(HANDLE hThread);
DWORD contextFlags(void)const;
void contextFlags(DWORD contextFlags);
DWORD dr0(void)const;
void dr0(DWORD dr0);
DWORD dr1(void)const;
void dr1(DWORD dr1);
DWORD dr2(void)const;
void dr2(DWORD dr2);
DWORD dr3(void)const;
void dr3(DWORD dr3);
DWORD dr6(void)const;
void dr6(DWORD dr6);
DWORD dr7(void)const;
void dr7(DWORD dr7);
FloatingSaveArea floatingSaveArea(void)const;
void floatingSaveArea(const FloatingSaveArea &someFloatingSaveArea);
DWORD segCS(void)const;
void segCS(DWORD segCS);
DWORD segGS(void)const;
void segGS(DWORD segGS);
DWORD segFS(void)const;
void segFS(DWORD segGS);
DWORD segES(void)const;
void segES(DWORD segGS);
DWORD segDS(void)const;
void segDS(DWORD segGS);
DWORD segSS(void)const;
void segSS(DWORD segSS);
DWORD edi(void)const;
void edi(DWORD edi);
DWORD esi(void)const;
void esi(DWORD esi);
DWORD ebx(void)const;
void ebx(DWORD ebx);
DWORD edx(void)const;
void edx(DWORD edx);
DWORD ecx(void)const;
void ecx(DWORD ecx);
DWORD eax(void)const;
void eax(DWORD eax);
DWORD ebp(void)const;
void ebp(DWORD ebp);
DWORD eip(void)const;
void eip(DWORD eip);
DWORD esp(void)const;
void esp(DWORD esp);
DWORD eFlags(void)const;
void eFlags(DWORD eFlags);
BOOL cf(void)const;
BOOL zf(void)const;
BOOL sf(void)const;
BOOL of(void)const;
BOOL pf(void)const;
BOOL af(void)const;
BOOL ie(void)const;
BOOL df(void)const;
private:
enum FlagMask{MaskCarry=0x0001,MaskZero=0x0040,MaskSign=0x0080,MaskOverflow=0x0800,MaskParity=0x0004,
MaskAuxiliaryCarry=0x0010,MaskInterruptEnable=0x0200,MaskDirection=0x0400};
void setZero(void);
};
inline
Context::Context(void)
{
setZero();
contextFlags(Full);
}
inline
Context::Context(const Context &someContext)
{
*this=someContext;
}
inline
Context::Context(const CONTEXT &someCONTEXT)
{
*this=someCONTEXT;
}
inline
Context::~Context(void)
{
}
inline
Context &Context::operator=(const Context &someContext)
{
::memcpy((char*)&((CONTEXT&)*this),(char*)&((CONTEXT&)someContext),sizeof(CONTEXT));
return *this;
}
inline
Context &Context::operator=(const CONTEXT &someCONTEXT)
{
::memcpy((char*)&((CONTEXT&)*this),(char*)&someCONTEXT,sizeof(CONTEXT));
return *this;
}
inline
WORD Context::operator==(const Context &someContext)const
{
return (::memcmp((char*)&((CONTEXT&)*this),(char*)&((CONTEXT&)someContext),sizeof(CONTEXT))?FALSE:TRUE);
}
inline
WORD Context::operator==(const CONTEXT &someCONTEXT)const
{
return (::memcmp((char*)&((CONTEXT&)*this),(char*)&someCONTEXT,sizeof(CONTEXT))?FALSE:TRUE);
}
inline
Context::operator String(void)const
{
String contextString;
contextString.reserve(String::MaxString*4);
::sprintf(contextString,"EAX:%08lx EBX:%08lx ECX:%08lx EDX:%08lx EIP:%08lx EBP:%08lx ESP:%08lx EDI:%08lx ESI:%08lx\nDR0:%08lx DR1:%08lx DR2:%08lx DR3:%08lx DR6:%08lx DR7:%08lx\nCS:%08lx GS:%08lx FS:%08lx ES:%08lx DS:%08lx SS:%08lx Flags:%08lx",
eax(),ebx(),ecx(),edx(),eip(),ebp(),esp(),edi(),esi(),
dr0(),dr1(),dr2(),dr3(),dr6(),dr7(),
segCS(),segGS(),segFS(),segES(),segDS(),segSS(),eFlags());
return contextString;
}
inline
DWORD Context::contextFlags(void)const
{
return CONTEXT::ContextFlags;
}
inline
void Context::contextFlags(DWORD contextFlags)
{
CONTEXT::ContextFlags=contextFlags;
}
inline
DWORD Context::dr0(void)const
{
return CONTEXT::Dr0;
}
inline
void Context::dr0(DWORD dr0)
{
CONTEXT::Dr0=dr0;
}
inline
DWORD Context::dr1(void)const
{
return CONTEXT::Dr1;
}
inline
void Context::dr1(DWORD dr1)
{
CONTEXT::Dr1=dr1;
}
inline
DWORD Context::dr2(void)const
{
return CONTEXT::Dr2;
}
inline
void Context::dr2(DWORD dr2)
{
CONTEXT::Dr2=dr2;
}
inline
DWORD Context::dr3(void)const
{
return CONTEXT::Dr3;
}
inline
void Context::dr3(DWORD dr3)
{
CONTEXT::Dr3=dr3;
}
inline
DWORD Context::dr6(void)const
{
return CONTEXT::Dr6;
}
inline
void Context::dr6(DWORD dr6)
{
CONTEXT::Dr6=dr6;
}
inline
DWORD Context::dr7(void)const
{
return CONTEXT::Dr7;
}
inline
void Context::dr7(DWORD dr7)
{
CONTEXT::Dr7=dr7;
}
inline
FloatingSaveArea Context::floatingSaveArea(void)const
{
return FloatingSaveArea(CONTEXT::FloatSave);
}
inline
void Context::floatingSaveArea(const FloatingSaveArea &someFloatingSaveArea)
{
::memcpy((char*)&FloatSave,(char*)&((FLOATING_SAVE_AREA&)someFloatingSaveArea),sizeof(FLOATING_SAVE_AREA));
}
inline
DWORD Context::segCS(void)const
{
return CONTEXT::SegCs;
}
inline
void Context::segCS(DWORD segCS)
{
CONTEXT::SegCs=segCS;
}
inline
DWORD Context::segGS(void)const
{
return CONTEXT::SegGs;
}
inline
void Context::segGS(DWORD segGS)
{
CONTEXT::SegGs=segGS;
}
inline
DWORD Context::segFS(void)const
{
return CONTEXT::SegFs;
}
inline
void Context::segFS(DWORD segFS)
{
CONTEXT::SegFs=segFS;
}
inline
DWORD Context::segES(void)const
{
return CONTEXT::SegEs;
}
inline
void Context::segES(DWORD segES)
{
CONTEXT::SegEs=segES;
}
inline
DWORD Context::segDS(void)const
{
return CONTEXT::SegDs;
}
inline
void Context::segDS(DWORD segDS)
{
CONTEXT::SegDs=segDS;
}
inline
DWORD Context::segSS(void)const
{
return CONTEXT::SegSs;
}
inline
void Context::segSS(DWORD segSS)
{
CONTEXT::SegSs=segSS;
}
inline
DWORD Context::edi(void)const
{
return CONTEXT::Edi;
}
inline
void Context::edi(DWORD edi)
{
CONTEXT::Edi=edi;
}
inline
DWORD Context::esi(void)const
{
return CONTEXT::Esi;
}
inline
void Context::esi(DWORD esi)
{
CONTEXT::Esi=esi;
}
inline
DWORD Context::ebx(void)const
{
return CONTEXT::Ebx;
}
inline
void Context::ebx(DWORD ebx)
{
CONTEXT::Ebx=ebx;
}
inline
DWORD Context::edx(void)const
{
return CONTEXT::Edx;
}
inline
void Context::edx(DWORD edx)
{
CONTEXT::Edx=edx;
}
inline
DWORD Context::ecx(void)const
{
return CONTEXT::Ecx;
}
inline
void Context::ecx(DWORD ecx)
{
CONTEXT::Ecx=ecx;
}
inline
DWORD Context::eax(void)const
{
return CONTEXT::Eax;
}
inline
void Context::eax(DWORD eax)
{
CONTEXT::Eax=eax;
}
inline
DWORD Context::ebp(void)const
{
return CONTEXT::Ebp;
}
inline
void Context::ebp(DWORD ebp)
{
CONTEXT::Ebp=ebp;
}
inline
DWORD Context::eip(void)const
{
return CONTEXT::Eip;
}
inline
void Context::eip(DWORD eip)
{
CONTEXT::Eip=eip;
}
inline
DWORD Context::esp(void)const
{
return CONTEXT::Esp;
}
inline
void Context::esp(DWORD esp)
{
CONTEXT::Esp=esp;
}
inline
DWORD Context::eFlags(void)const
{
return CONTEXT::EFlags;
}
inline
void Context::eFlags(DWORD eFlags)
{
CONTEXT::EFlags=eFlags;
}
inline
BOOL Context::cf(void)const
{
return eFlags()&MaskCarry?TRUE:FALSE;
}
inline
BOOL Context::zf(void)const
{
return eFlags()&MaskZero?TRUE:FALSE;
}
inline
BOOL Context::sf(void)const
{
return eFlags()&MaskSign?TRUE:FALSE;
}
inline
BOOL Context::of(void)const
{
return eFlags()&MaskOverflow?TRUE:FALSE;
}
inline
BOOL Context::pf(void)const
{
return eFlags()&MaskParity?TRUE:FALSE;
}
inline
BOOL Context::af(void)const
{
return eFlags()&MaskAuxiliaryCarry?TRUE:FALSE;
}
inline
BOOL Context::ie(void)const
{
return eFlags()&&MaskInterruptEnable?TRUE:FALSE;
}
inline
BOOL Context::df(void)const
{
return eFlags()&MaskDirection?TRUE:FALSE;
}
inline
void Context::setZero(void)
{
::memset((char*)&((CONTEXT&)*this),0,sizeof(CONTEXT));
}
inline
WORD Context::getThreadContext(HANDLE hThread)
{
return ::GetThreadContext(hThread,&((CONTEXT&)*this));
}
inline
WORD Context::setThreadContext(HANDLE hThread)
{
return ::SetThreadContext(hThread,&((CONTEXT&)*this));
}
#endif

40
thread/EVENT.CPP Normal file
View File

@@ -0,0 +1,40 @@
#include <thread/event.hpp>
#include <thread/postfix.hpp>
Event::Event(BOOL manualReset)
: mhEvent(0), mEventName("Event")
{
PostFix postFix;
postFix.postFix(mEventName);
mhEvent=::CreateEvent((LPSECURITY_ATTRIBUTES)0,manualReset,FALSE,mEventName);
}
Event::Event(const String &eventName,BOOL postFixup,BOOL manualReset)
: mhEvent(0)
{
PostFix postFix;
if(eventName.isNull())return;
mEventName=eventName;
if(postFixup)postFix.postFix(mEventName);
mhEvent=::CreateEvent((LPSECURITY_ATTRIBUTES)0,manualReset,FALSE,mEventName);
}
WORD Event::waitEvent(DWORD timeOut,WORD alertable)const
{
DWORD waitResult;
if(!isOkay())return FALSE;
waitResult=::WaitForSingleObjectEx(mhEvent,timeOut,alertable);
if(WAIT_ABANDONED==waitResult)return FALSE;
else if(WAIT_TIMEOUT==waitResult)return FALSE;
else if(WAIT_OBJECT_0==waitResult)return TRUE;
else return TRUE;
}
WORD Event::closeEvent(void)
{
if(!isOkay())return FALSE;
::CloseHandle(mhEvent);
mhEvent=0;
return TRUE;
}

86
thread/EVENT.HPP Normal file
View File

@@ -0,0 +1,86 @@
#ifndef _THREAD_EVENT_HPP_
#define _THREAD_EVENT_HPP_
#ifndef _COMMON_STDIO_HPP_
#include <common/stdio.hpp>
#endif
#ifndef _COMMON_WINDOWS_HPP_
#include <common/windows.hpp>
#endif
#ifndef _COMMON_STRING_HPP_
#include <common/string.hpp>
#endif
class Event
{
public:
Event(BOOL manualReset=TRUE);
Event(const String &eventName,BOOL postFixup=TRUE,BOOL manualReset=TRUE);
virtual ~Event();
operator HANDLE(void);
WORD setEvent(void)const;
WORD pulseEvent(void)const;
WORD resetEvent(void)const;
WORD waitEvent(DWORD timeOut=INFINITE,WORD alertable=FALSE)const;
WORD closeEvent(void);
BOOL openEvent(const String &strEventName);
BOOL isOkay(void)const;
const String &eventName(void)const;
private:
HANDLE mhEvent;
String mEventName;
};
inline
Event::~Event()
{
closeEvent();
}
inline
Event::operator HANDLE(void)
{
return mhEvent;
}
inline
WORD Event::setEvent(void)const
{
if(!mhEvent)return FALSE;
return ::SetEvent(mhEvent);
}
inline
WORD Event::pulseEvent(void)const
{
if(!mhEvent)return FALSE;
return ::PulseEvent(mhEvent);
}
inline
WORD Event::resetEvent(void)const
{
if(!mhEvent)return FALSE;
return ::ResetEvent(mhEvent);
}
inline
const String &Event::eventName(void)const
{
return mEventName;
}
inline
BOOL Event::isOkay(void)const
{
return mhEvent?TRUE:FALSE;
}
inline
BOOL Event::openEvent(const String &strEventName)
{
closeEvent();
mEventName=strEventName;
mhEvent=::OpenEvent(EVENT_ALL_ACCESS,TRUE,(LPSTR)(String&)strEventName);
return isOkay();
}
#endif

71
thread/MONITOR.HPP Normal file
View File

@@ -0,0 +1,71 @@
#ifndef _THREAD_MONITOR_HPP_
#define _THREAD_MONITOR_HPP_
#ifndef _THREAD_MUTEX_HPP_
#include <thread/mutex.hpp>
#endif
template <class T>
class Monitor
{
public:
Monitor(void);
virtual ~Monitor();
void enter(void);
void leave(void);
T *operator->(void);
operator T*(void);
Monitor &operator=(T *pObj);
private:
T *mlpObj;
Mutex mMutex;
};
template <class T>
inline
Monitor<T>::Monitor(void)
: mlpObj(0)
{
}
template <class T>
inline
Monitor<T>::~Monitor()
{
}
template <class T>
inline
T *Monitor<T>::operator->(void)
{
return mlpObj;
}
template <class T>
inline
Monitor<T>::operator T*(void)
{
return mlpObj;
}
template <class T>
inline
Monitor<T> &Monitor<T>::operator=(T *pObj)
{
mlpObj=pObj;
return *this;
}
template <class T>
inline
void Monitor<T>::enter(void)
{
mMutex.requestMutex();
}
template <class T>
inline
void Monitor<T>::leave(void)
{
mMutex.releaseMutex();
}
#endif

123
thread/MSGQUEUE.CPP Normal file
View File

@@ -0,0 +1,123 @@
#include <thread/msgqueue.hpp>
WORD MessageQueue::postMessage(ThreadMessage &someThreadMessage)
{
mMutexSemaphore.requestMutex();
mNamedEvent.resetEvent();
if(isQueueLocked()){mMutexSemaphore.releaseMutex();return FALSE;}
putQueueMessage(someThreadMessage);
mNamedEvent.setEvent();
mMutexSemaphore.releaseMutex();
return TRUE;
}
WORD MessageQueue::itemsInQueue(void)
{
WORD queueMessages;
mMutexSemaphore.requestMutex();
queueMessages=mMessageQueueHigh.size();
queueMessages+=mMessageQueueNormal.size();
queueMessages+=mMessageQueueLow.size();
mMutexSemaphore.releaseMutex();
return queueMessages;
}
WORD MessageQueue::waitMessage(ThreadMessage &someThreadMessage)
{
mNamedEvent.waitEvent(INFINITE,mIsAlertable);
mMutexSemaphore.requestMutex();
if(!getQueueMessage(someThreadMessage))
{
mMutexSemaphore.releaseMutex();
mNamedEvent.resetEvent();
return FALSE;
}
if(isQueueEmpty())mNamedEvent.resetEvent();
mMutexSemaphore.releaseMutex();
return TRUE;
}
WORD MessageQueue::peekMessage(ThreadMessage &someThreadMessage)
{
WORD returnCode;
mMutexSemaphore.requestMutex();
returnCode=peekQueueMessage(someThreadMessage);
mMutexSemaphore.releaseMutex();
return returnCode;
}
WORD MessageQueue::putQueueMessage(ThreadMessage &someThreadMessage)
{
if(ThreadMessage::PriorityNormal==someThreadMessage.priority())
mMessageQueueNormal.insert(&someThreadMessage);
else if(ThreadMessage::PriorityHigh==someThreadMessage.priority())
mMessageQueueHigh.insert(&someThreadMessage);
else mMessageQueueLow.insert(&someThreadMessage);
return TRUE;
}
WORD MessageQueue::getQueueMessage(ThreadMessage &someThreadMessage)
{
if(isQueueEmpty())return FALSE;
if(mMessageQueueHigh.size())
{
someThreadMessage=mMessageQueueHigh[0];
mMessageQueueHigh.remove(0L);
}
else if(mMessageQueueNormal.size())
{
someThreadMessage=mMessageQueueNormal[0];
mMessageQueueNormal.remove(0L);
}
else
{
someThreadMessage=mMessageQueueLow[0];
mMessageQueueLow.remove(0L);
}
return TRUE;
}
WORD MessageQueue::peekQueueMessage(ThreadMessage &someThreadMessage)
{
if(isQueueEmpty())return FALSE;
if(mMessageQueueHigh.size())someThreadMessage=mMessageQueueHigh[mMessageQueueHigh.size()-1];
else if(mMessageQueueNormal.size())someThreadMessage=mMessageQueueNormal[mMessageQueueNormal.size()-1];
else if(mMessageQueueLow.size())someThreadMessage=mMessageQueueLow[mMessageQueueLow.size()-1];
else return FALSE;
return TRUE;
}
WORD MessageQueue::isQueueEmpty(void)const
{
WORD queueMessages;
queueMessages=mMessageQueueHigh.size();
queueMessages+=mMessageQueueNormal.size();
queueMessages+=mMessageQueueLow.size();
return (0==queueMessages);
}
void MessageQueue::shutdownQueue(void)
{
mMutexSemaphore.requestMutex();
mMessageQueueHigh.remove();
mMessageQueueNormal.remove();
mMessageQueueLow.remove();
mQueueStatus=QueueLocked;
mMutexSemaphore.releaseMutex();
mNamedEvent.setEvent();
}
void MessageQueue::restartQueue(void)
{
mMutexSemaphore.requestMutex();
mMessageQueueHigh.remove();
mMessageQueueNormal.remove();
mMessageQueueLow.remove();
mQueueStatus=QueueOpen;
mMutexSemaphore.releaseMutex();
mNamedEvent.setEvent();
}

71
thread/MSGQUEUE.HPP Normal file
View File

@@ -0,0 +1,71 @@
#ifndef _THREAD_MESSAGEQUEUE_HPP_
#define _THREAD_MESSAGEQUEUE_HPP_
#ifndef _COMMON_WINDOWS_HPP_
#include <common/windows.hpp>
#endif
#ifndef _COMMON_BLOCK_HPP_
#include <common/block.hpp>
#endif
#ifndef _THREAD_EVENT_HPP_
#include <thread/event.hpp>
#endif
#ifndef _THREAD_MUTEX_HPP_
#include <thread/mutex.hpp>
#endif
#ifndef _THREAD_THREADMESSAGE_HPP_
#include <thread/thmsg.hpp>
#endif
class MessageQueue
{
public:
enum QueueStatus{QueueLocked,QueueOpen};
MessageQueue(void);
virtual ~MessageQueue();
WORD postMessage(ThreadMessage &someThreadMessage);
WORD peekMessage(ThreadMessage &someThreadMessage);
WORD waitMessage(ThreadMessage &someThreadMessage);
WORD itemsInQueue(void);
void shutdownQueue(void);
void restartQueue(void);
void isAlertable(WORD isAlertable);
private:
WORD putQueueMessage(ThreadMessage &someThreadMessage);
WORD peekQueueMessage(ThreadMessage &someThreadMessage);
WORD getQueueMessage(ThreadMessage &someThreadMessage);
WORD isQueueEmpty(void)const;
WORD isQueueLocked(void)const;
WORD mIsAlertable;
Event mNamedEvent;
Mutex mMutexSemaphore;
QueueStatus mQueueStatus;
Block<ThreadMessage> mMessageQueueHigh;
Block<ThreadMessage> mMessageQueueNormal;
Block<ThreadMessage> mMessageQueueLow;
};
inline
MessageQueue::MessageQueue(void)
: mNamedEvent("MESSAGEQUEUENAMEDEVENT"), mMutexSemaphore("MESSAGEQUEUENAMEDMUTEX"),
mQueueStatus(QueueOpen), mIsAlertable(FALSE)
{
}
inline
MessageQueue::~MessageQueue()
{
}
inline
WORD MessageQueue::isQueueLocked(void)const
{
return QueueLocked==mQueueStatus;
}
inline
void MessageQueue::isAlertable(WORD isAlertable)
{
mIsAlertable=isAlertable;
}
#endif

104
thread/MTHREAD.BAK Normal file
View File

@@ -0,0 +1,104 @@
#ifndef _THREAD_MESSAGETHREAD_HPP_
#define _THREAD_MESSAGETHREAD_HPP_
#ifndef _COMMON_BLOCK_HPP_
#include <common/block.hpp>
#endif
#ifndef _THREAD_QUEUETHREAD_HPP_
#include <thread/qthread.hpp>
#endif
#ifndef _THREAD_MESSAGEQUEUE_HPP_
#include <thread/msgqueue.hpp>
#endif
#ifndef _THREAD_THREADCALLBACK_HPP_
#include <thread/tcallbck.hpp>
#endif
class MessageThread : private QueueThread
{
public:
MessageThread(void);
virtual ~MessageThread();
WORD postMessage(ThreadMessage &someThreadMessage);
WORD sendMessage(ThreadMessage &someThreadMessage);
WORD peekMessage(ThreadMessage &someThreadMessage);
WORD messageCount(void);
DWORD suspend(void);
DWORD resume(void);
DWORD wait(DWORD timeout)const;
void stop(void);
void isAlertable(WORD isAlertable);
WORD insertHandler(PureThreadCallback *lpThreadCallback);
void removeHandler(PureThreadCallback *lpThreadCallback);
private:
WORD getMessage(ThreadMessage &someThreadMessage);
void dispatchMessage(ThreadMessage &someThreadMessage);
void startup(void);
void shutdown(void);
void messageLoop(void);
void removeHandlers(void);
MessageQueue mMessageQueue;
Mutex mMessageThreadMutex;
Block<ThreadCallbackPointer> mThreadCallback;
};
inline
WORD MessageThread::postMessage(ThreadMessage &someThreadMessage)
{
someThreadMessage.messageTime().refresh();
mMessageQueue.postMessage(someThreadMessage);
return TRUE;
}
inline
WORD MessageThread::sendMessage(ThreadMessage &someThreadMessage)
{
someThreadMessage.messageTime().refresh();
someThreadMessage.priority(ThreadMessage::PriorityHigh);
postMessage(someThreadMessage);
::SleepEx(0,FALSE); // give up remainder of quantum so message can be processed
return TRUE;
}
inline
WORD MessageThread::getMessage(ThreadMessage &someThreadMessage)
{
return mMessageQueue.waitMessage(someThreadMessage);
}
inline
WORD MessageThread::peekMessage(ThreadMessage &someThreadMessage)
{
return mMessageQueue.peekMessage(someThreadMessage);
}
inline
WORD MessageThread::messageCount(void)
{
return mMessageQueue.itemsInQueue();
}
inline
DWORD MessageThread::suspend(void)
{
return QueueThread::suspend();
}
inline
DWORD MessageThread::resume(void)
{
return QueueThread::resume();
}
inline
DWORD MessageThread::wait(DWORD timeout)const
{
return QueueThread::wait(timeout);
}
inline
void MessageThread::isAlertable(WORD isAlertable)
{
mMessageQueue.isAlertable(isAlertable);
}
#endif

93
thread/MTHREAD.CPP Normal file
View File

@@ -0,0 +1,93 @@
#include <thread/mthread.hpp>
MessageThread::MessageThread(bool startup)
: mMessageThreadMutex("MessageThreadMutex")
{
if(startup)start();
}
MessageThread::~MessageThread()
{
stop();
}
void MessageThread::stop(void)
{
ThreadMessage threadMessage(ThreadMessage::TM_DESTROY,0L,0L,ThreadMessage::PriorityHigh);
if(!isRunning())return;
QueueThread::stop();
resume();
sendMessage(threadMessage);
removeHandlers();
wait(INFINITE);
mMessageQueue.shutdownQueue();
}
WORD MessageThread::insertHandler(PureThreadCallback *lpThreadCallback)
{
WORD returnCode;
mMessageThreadMutex.requestMutex();
mThreadCallback.insert(&ThreadCallbackPointer(lpThreadCallback));
returnCode=mThreadCallback.size();
mMessageThreadMutex.releaseMutex();
return returnCode;
}
void MessageThread::removeHandler(PureThreadCallback *lpThreadCallback)
{
size_t itemCount;
mMessageThreadMutex.requestMutex();
itemCount=(size_t)mThreadCallback.size();
for(short vectorIndex=0;vectorIndex<itemCount;vectorIndex++)
{
if(mThreadCallback[vectorIndex]==ThreadCallbackPointer(lpThreadCallback))
{
mThreadCallback.remove(vectorIndex);
itemCount=(size_t)mThreadCallback.size();
vectorIndex=-1;
}
}
mMessageThreadMutex.releaseMutex();
}
void MessageThread::removeHandlers(void)
{
mMessageThreadMutex.requestMutex();
mThreadCallback.remove();
mMessageThreadMutex.releaseMutex();
}
void MessageThread::dispatchMessage(ThreadMessage &someThreadMessage)
{
size_t itemCount;
mMessageThreadMutex.requestMutex();
itemCount=(size_t)mThreadCallback.size();
for(short vectorIndex=0;vectorIndex<itemCount;vectorIndex++)
mThreadCallback[vectorIndex].callback(someThreadMessage);
mMessageThreadMutex.releaseMutex();
}
// *** virtual overload of QueueMessage
void MessageThread::startup(void)
{
ThreadMessage threadMessage(ThreadMessage::TM_CREATE,0L);
sendMessage(threadMessage);
}
void MessageThread::messageLoop(void)
{
ThreadMessage threadMessage;
while(isRunning())if(mMessageQueue.waitMessage(threadMessage))dispatchMessage(threadMessage);
}
void MessageThread::shutdown(void)
{
return;
}

105
thread/MTHREAD.HPP Normal file
View File

@@ -0,0 +1,105 @@
#ifndef _THREAD_MESSAGETHREAD_HPP_
#define _THREAD_MESSAGETHREAD_HPP_
#ifndef _COMMON_BLOCK_HPP_
#include <common/block.hpp>
#endif
#ifndef _THREAD_QUEUETHREAD_HPP_
#include <thread/qthread.hpp>
#endif
#ifndef _THREAD_MESSAGEQUEUE_HPP_
#include <thread/msgqueue.hpp>
#endif
#ifndef _THREAD_THREADCALLBACK_HPP_
#include <thread/tcallbck.hpp>
#endif
class MessageThread : protected QueueThread
{
public:
MessageThread(bool startup=true);
virtual ~MessageThread();
WORD postMessage(ThreadMessage &someThreadMessage);
WORD sendMessage(ThreadMessage &someThreadMessage);
WORD peekMessage(ThreadMessage &someThreadMessage);
WORD messageCount(void);
DWORD suspend(void);
DWORD resume(void);
DWORD wait(DWORD timeout=INFINITE,bool alertable=false)const;
void stop(void);
void isAlertable(WORD isAlertable);
WORD insertHandler(PureThreadCallback *lpThreadCallback);
void removeHandler(PureThreadCallback *lpThreadCallback);
protected:
void startup(void);
void shutdown(void);
void messageLoop(void);
private:
WORD getMessage(ThreadMessage &someThreadMessage);
void dispatchMessage(ThreadMessage &someThreadMessage);
void removeHandlers(void);
MessageQueue mMessageQueue;
Mutex mMessageThreadMutex;
Block<ThreadCallbackPointer> mThreadCallback;
};
inline
WORD MessageThread::postMessage(ThreadMessage &someThreadMessage)
{
someThreadMessage.messageTime().refresh();
mMessageQueue.postMessage(someThreadMessage);
return TRUE;
}
inline
WORD MessageThread::sendMessage(ThreadMessage &someThreadMessage)
{
someThreadMessage.messageTime().refresh();
someThreadMessage.priority(ThreadMessage::PriorityHigh);
postMessage(someThreadMessage);
::SleepEx(0,FALSE); // give up remainder of quantum so message can be processed
return TRUE;
}
inline
WORD MessageThread::getMessage(ThreadMessage &someThreadMessage)
{
return mMessageQueue.waitMessage(someThreadMessage);
}
inline
WORD MessageThread::peekMessage(ThreadMessage &someThreadMessage)
{
return mMessageQueue.peekMessage(someThreadMessage);
}
inline
WORD MessageThread::messageCount(void)
{
return mMessageQueue.itemsInQueue();
}
inline
DWORD MessageThread::suspend(void)
{
return QueueThread::suspend();
}
inline
DWORD MessageThread::resume(void)
{
return QueueThread::resume();
}
inline
DWORD MessageThread::wait(DWORD timeout,bool alertable)const
{
return QueueThread::wait(timeout,alertable);
}
inline
void MessageThread::isAlertable(WORD isAlertable)
{
mMessageQueue.isAlertable(isAlertable);
}
#endif

48
thread/MUTEX.CPP Normal file
View File

@@ -0,0 +1,48 @@
#include <thread/mutex.hpp>
#include <thread/postfix.hpp>
Mutex::Mutex(void)
: mhMutex(0), mMutexName("Mutex")
{
PostFix postFix;
postFix.postFix(mMutexName);
mhMutex=::CreateMutex((LPSECURITY_ATTRIBUTES)0,FALSE,mMutexName);
}
Mutex::Mutex(const String &mutexName,BOOL postFixup)
: mhMutex(0)
{
PostFix postFix;
if(mutexName.isNull())return;
mMutexName=mutexName;
if(postFixup)postFix.postFix(mMutexName);
mhMutex=::CreateMutex((LPSECURITY_ATTRIBUTES)0,FALSE,mMutexName);
}
WORD Mutex::requestMutex(DWORD waitTime,WORD alertable)const
{
DWORD waitResult;
if(!isOkay())return FALSE;
waitResult=::WaitForSingleObjectEx(mhMutex,waitTime,alertable);
if(WAIT_ABANDONED==waitResult)return FALSE;
else if(WAIT_TIMEOUT==waitResult)return FALSE;
else if(WAIT_OBJECT_0==waitResult)return TRUE;
else return TRUE;
return TRUE;
}
WORD Mutex::releaseMutex(void)const
{
if(!isOkay())return FALSE;
return ::ReleaseMutex(mhMutex);
}
WORD Mutex::closeMutex(void)
{
if(!isOkay())return FALSE;
::CloseHandle(mhMutex);
mhMutex=0;
return TRUE;
}

56
thread/MUTEX.HPP Normal file
View File

@@ -0,0 +1,56 @@
#ifndef _THREAD_MUTEX_HPP_
#define _THREAD_MUTEX_HPP_
#ifndef _COMMON_STDIO_HPP_
#include <common/stdio.hpp>
#endif
#ifndef _COMMON_WINDOWS_HPP_
#include <common/windows.hpp>
#endif
#ifndef _COMMON_STRING_HPP_
#include <common/string.hpp>
#endif
class Mutex
{
public:
Mutex(void);
Mutex(const String &mutexName,BOOL postFixup=TRUE);
virtual ~Mutex();
WORD requestMutex(DWORD waitTime=INFINITE,WORD alertable=FALSE)const;
WORD releaseMutex(void)const;
WORD closeMutex(void);
BOOL openMutex(const String &strMutexName);
const String &mutexName(void)const;
BOOL isOkay(void)const;
private:
HANDLE mhMutex;
String mMutexName;
};
inline
Mutex::~Mutex()
{
closeMutex();
}
inline
BOOL Mutex::openMutex(const String &strMutexName)
{
closeMutex();
mMutexName=strMutexName;
mhMutex=::OpenMutex(EVENT_ALL_ACCESS,TRUE,(LPSTR)(String&)strMutexName);
return isOkay();
}
inline
const String &Mutex::mutexName(void)const
{
return mMutexName;
}
inline
BOOL Mutex::isOkay(void)const
{
return mhMutex?TRUE:FALSE;
}
#endif

47
thread/POSTFIX.HPP Normal file
View File

@@ -0,0 +1,47 @@
#ifndef _THREAD_POSTFIX_HPP_
#define _THREAD_POSTFIX_HPP_
class PostFix
{
public:
PostFix(void);
virtual ~PostFix();
void postFix(String &eventName)const;
private:
PostFix(const PostFix &somePostFix);
PostFix &operator=(const PostFix &somePostFix);
};
inline
PostFix::PostFix(void)
{
}
inline
PostFix::PostFix(const PostFix &/*somePostFix*/)
{
}
inline
PostFix::~PostFix()
{
}
inline
PostFix &PostFix::operator=(const PostFix &/*somePostFix*/)
{
return *this;
}
inline
void PostFix::postFix(String &eventName)const
{
String eventNamePostFix;
String invalidTokens(":./\\");
eventName.removeTokens(invalidTokens);
::sprintf(eventNamePostFix,"@%ld@%ld",(LONG)this,::GetTickCount());
eventName+=eventNamePostFix;
}
#endif

6
thread/PTCLLBCK.CPP Normal file
View File

@@ -0,0 +1,6 @@
#include <thread/ptcllbck.hpp>
DWORD PureThreadCallback::operator*(ThreadMessage &/*someCallbackData*/)
{
return 0;
}

25
thread/PTCLLBCK.HPP Normal file
View File

@@ -0,0 +1,25 @@
#ifndef _THREAD_PURETHREADCALLBACK_HPP_
#define _THREAD_PURETHREADCALLBACK_HPP_
#ifndef _THREAD_THREADMESSAGE_HPP_
#include <thread/thmsg.hpp>
#endif
class PureThreadCallback
{
public:
PureThreadCallback(void);
virtual ~PureThreadCallback();
virtual DWORD operator*(ThreadMessage &someThreadMessage)=0;
private:
};
inline
PureThreadCallback::PureThreadCallback(void)
{
}
inline
PureThreadCallback::~PureThreadCallback()
{
}
#endif

43
thread/QTHREAD.CPP Normal file
View File

@@ -0,0 +1,43 @@
#include <thread/qthread.hpp>
#include <thread/msgqueue.hpp>
DWORD WINAPI QueueThread::sThreadProc(LPVOID lpInstanceData)
{
String infoBuff;
::sprintf(infoBuff,"<QueueThread::sThreadProc> Thread 0x%08lx started.\n",::GetCurrentThreadId());
::OutputDebugString(infoBuff);
QueueThread &queueThread=(*((QueueThread*)lpInstanceData));
queueThread.mQueueThreadDestructorMutex.requestMutex();
queueThread.startupex();
queueThread.startup();
queueThread.messageLoop();
queueThread.shutdown();
queueThread.mQueueThreadDestructorMutex.releaseMutex();
::sprintf(infoBuff,"<QueueThread::sThreadProc> Thread 0x%08lx exited normally.\n",::GetCurrentThreadId());
::OutputDebugString(infoBuff);
return FALSE;
}
void QueueThread::startupex(void)
{
mQueueThreadStartupEvent.setEvent();
}
// virtual defaults
void QueueThread::startup(void)
{
return;
}
void QueueThread::messageLoop(void)
{
return;
}
void QueueThread::shutdown(void)
{
return;
}

71
thread/QTHREAD.HPP Normal file
View File

@@ -0,0 +1,71 @@
#ifndef _THREAD_QUEUETHREAD_HPP_
#define _THREAD_QUEUETHREAD_HPP_
#ifndef _THREAD_PURETHREAD_HPP_
#include <thread/thread.hpp>
#endif
#ifndef _THREAD_THREADMESSAGE_HPP_
#include <thread/thmsg.hpp>
#endif
#ifndef _THREAD_MUTEX_HPP_
#include <thread/mutex.hpp>
#endif
#ifndef _THREAD_EVENT_HPP_
#include <thread/event.hpp>
#endif
class QueueThread : public PureThread
{
public:
QueueThread(void);
virtual ~QueueThread();
WORD start(void);
void stop(void);
WORD isRunning(void)const;
protected:
virtual void startup(void);
virtual void shutdown(void);
virtual void messageLoop(void);
private:
void startupex(void);
static DWORD WINAPI sThreadProc(LPVOID lpInstanceData);
WORD mIsRunning;
Mutex mQueueThreadDestructorMutex;
Event mQueueThreadStartupEvent;
};
inline
QueueThread::QueueThread(void)
: PureThread(sThreadProc), mIsRunning(FALSE),
mQueueThreadDestructorMutex("QUEUETHREADDESTRUCTORMUTEX"),
mQueueThreadStartupEvent("QUEUETHREADSTARTUPEVENT")
{
}
inline
QueueThread::~QueueThread()
{
mQueueThreadDestructorMutex.requestMutex();
mQueueThreadDestructorMutex.releaseMutex();
}
inline
WORD QueueThread::start(void)
{
if(!PureThread::start((void*)this))return FALSE;
if(!(mIsRunning=PureThread::resume()))return FALSE;
mQueueThreadStartupEvent.waitEvent();
return mIsRunning;
}
inline
void QueueThread::stop(void)
{
mIsRunning=FALSE;
}
inline
WORD QueueThread::isRunning(void)const
{
return mIsRunning;
}
#endif

BIN
thread/Release/thread.lib Normal file

Binary file not shown.

BIN
thread/Release/vc60.idb Normal file

Binary file not shown.

186
thread/SAVEAREA.HPP Normal file
View File

@@ -0,0 +1,186 @@
#ifndef _THREAD_FLOATINGSAVEAREA_HPP_
#define _THREAD_FLOATINGSAVEAREA_HPP_
#ifndef _COMMON_WINDOWS_HPP_
#include <common/windows.hpp>
#endif
#ifndef _COMMON_WINNT_HPP_
#include <common/winnt.hpp>
#endif
class FloatingSaveArea : private FLOATING_SAVE_AREA
{
public:
FloatingSaveArea(void);
FloatingSaveArea(const FloatingSaveArea &someFloatingSaveArea);
FloatingSaveArea(const FLOATING_SAVE_AREA &someFLOATINGSAVEAREA);
virtual ~FloatingSaveArea();
FloatingSaveArea &operator=(const FloatingSaveArea &someFloatingSaveArea);
FloatingSaveArea &operator=(const FLOATING_SAVE_AREA &someFLOATINGSAVEAREA);
WORD operator==(const FloatingSaveArea &someFloatingSaveArea);
WORD operator==(const FLOATING_SAVE_AREA &someFLOATINGSAVEAREA);
BYTE &operator[](WORD itemIndex);
DWORD statusWord(void)const;
void statusWord(DWORD statusWord);
DWORD tagWord(void)const;
void tagWord(DWORD tagWord);
DWORD errorOffset(void)const;
void errorOffset(DWORD errorOffset);
DWORD errorSelector(void)const;
void errorSelector(DWORD errorSelector);
DWORD dataOffset(void)const;
void dataOffset(DWORD dataOffset);
DWORD dataSelector(void)const;
void dataSelector(DWORD dataSelector);
DWORD cr0NpxState(void)const;
void cr0NpxState(DWORD cr0NpxState);
private:
void setZero(void);
};
inline
FloatingSaveArea::FloatingSaveArea(void)
{
setZero();
}
inline
FloatingSaveArea::FloatingSaveArea(const FloatingSaveArea &someFloatingSaveArea)
{
*this=someFloatingSaveArea;
}
inline
FloatingSaveArea::FloatingSaveArea(const FLOATING_SAVE_AREA &someFLOATINGSAVEAREA)
{
*this=someFLOATINGSAVEAREA;
}
inline
FloatingSaveArea::~FloatingSaveArea()
{
}
inline
FloatingSaveArea &FloatingSaveArea::operator=(const FloatingSaveArea &someFloatingSaveArea)
{
::memcpy((char*)&((FLOATING_SAVE_AREA&)*this),(char*)&((FLOATING_SAVE_AREA&)someFloatingSaveArea),sizeof(FLOATING_SAVE_AREA));
return *this;
}
inline
FloatingSaveArea &FloatingSaveArea::operator=(const FLOATING_SAVE_AREA &someFLOATINGSAVEAREA)
{
::memcpy((char*)&((FLOATING_SAVE_AREA&)*this),(char*)&(someFLOATINGSAVEAREA),sizeof(FLOATING_SAVE_AREA));
return *this;
}
inline
WORD FloatingSaveArea::operator==(const FloatingSaveArea &someFloatingSaveArea)
{
return (::memcmp((char*)&((FLOATING_SAVE_AREA&)*this),(char*)&((FLOATING_SAVE_AREA&)someFloatingSaveArea),sizeof(FLOATING_SAVE_AREA))?FALSE:TRUE);
}
inline
WORD FloatingSaveArea::operator==(const FLOATING_SAVE_AREA &someFLOATINGSAVEAREA)
{
return (::memcmp((char*)&((FLOATING_SAVE_AREA&)*this),(char*)&((FLOATING_SAVE_AREA&)someFLOATINGSAVEAREA),sizeof(FLOATING_SAVE_AREA))?FALSE:TRUE);
}
inline
BYTE &FloatingSaveArea::operator[](WORD itemIndex)
{
if(itemIndex>=SIZE_OF_80387_REGISTERS)itemIndex=0;
return FLOATING_SAVE_AREA::RegisterArea[itemIndex];
}
inline
DWORD FloatingSaveArea::statusWord(void)const
{
return FLOATING_SAVE_AREA::StatusWord;
}
inline
void FloatingSaveArea::statusWord(DWORD statusWord)
{
FLOATING_SAVE_AREA::StatusWord=statusWord;
}
inline
DWORD FloatingSaveArea::tagWord(void)const
{
return FLOATING_SAVE_AREA::TagWord;
}
inline
void FloatingSaveArea::tagWord(DWORD tagWord)
{
FLOATING_SAVE_AREA::TagWord=tagWord;
}
inline
DWORD FloatingSaveArea::errorOffset(void)const
{
return FLOATING_SAVE_AREA::ErrorOffset;
}
inline
void FloatingSaveArea::errorOffset(DWORD errorOffset)
{
FLOATING_SAVE_AREA::ErrorOffset=errorOffset;
}
inline
DWORD FloatingSaveArea::errorSelector(void)const
{
return FLOATING_SAVE_AREA::ErrorSelector;
}
inline
void FloatingSaveArea::errorSelector(DWORD errorSelector)
{
FLOATING_SAVE_AREA::ErrorSelector=errorSelector;
}
inline
DWORD FloatingSaveArea::dataOffset(void)const
{
return FLOATING_SAVE_AREA::DataOffset;
}
inline
void FloatingSaveArea::dataOffset(DWORD dataOffset)
{
FLOATING_SAVE_AREA::DataOffset=dataOffset;
}
inline
DWORD FloatingSaveArea::dataSelector(void)const
{
return FLOATING_SAVE_AREA::DataSelector;
}
inline
void FloatingSaveArea::dataSelector(DWORD dataSelector)
{
FLOATING_SAVE_AREA::DataSelector=dataSelector;
}
inline
DWORD FloatingSaveArea::cr0NpxState(void)const
{
return FLOATING_SAVE_AREA::Cr0NpxState;
}
inline
void FloatingSaveArea::cr0NpxState(DWORD cr0NpxState)
{
FLOATING_SAVE_AREA::Cr0NpxState=cr0NpxState;
}
inline
void FloatingSaveArea::setZero(void)
{
::memset((char*)&((FLOATING_SAVE_AREA&)*this),0,sizeof(FLOATING_SAVE_AREA));
}
#endif

348
thread/SCRAPS.TXT Normal file
View File

@@ -0,0 +1,348 @@
WORD MessageQueue::waitMessage(ThreadMessage &someThreadMessage)
{
mNamedEvent.waitEvent(INFINITE,mIsAlertable);
// mNamedEvent.resetEvent();
mMutexSemaphore.requestMutex();
if(isQueueEmpty()){mMutexSemaphore.releaseMutex();mNamedEvent.resetEvent();return FALSE;}
getQueueMessage(someThreadMessage);
mMutexSemaphore.releaseMutex();
return TRUE;
}
WORD MessageQueue::getQueueMessage(ThreadMessage &someThreadMessage)
{
if(isQueueEmpty())return FALSE;
if(mMessageQueueHigh.size())
{
someThreadMessage=mMessageQueueHigh[0];
mMessageQueueHigh.remove(0L);
// someThreadMessage=mMessageQueueHigh[mMessageQueueHigh.size()-1];
// mMessageQueueHigh.remove(mMessageQueueHigh.size()-1);
}
else if(mMessageQueueNormal.size())
{
someThreadMessage=mMessageQueueNormal[0];
mMessageQueueNormal.remove(0L);
// someThreadMessage=mMessageQueueNormal[mMessageQueueNormal.size()-1];
// mMessageQueueNormal.remove(mMessageQueueNormal.size()-1);
}
else
{
someThreadMessage=mMessageQueueLow[0];
mMessageQueueLow.remove(0L);
// someThreadMessage=mMessageQueueLow[mMessageQueueLow.size()-1];
// mMessageQueueLow.remove(mMessageQueueLow.size()-1);
}
return TRUE;
}
WORD PureThread::start(LPVOID lpCreationData)
{
if(isOkay()||!mlpfnThreadProc)return FALSE;
mhThread=::CreateThread((SECURITY_ATTRIBUTES*)0,InitialStack,mlpfnThreadProc,lpCreationData,CREATE_SUSPENDED,&mThreadID);
mhThread=::
if(!mhThread)return FALSE;
mThreadStatus=InSuspend;
return TRUE;
}
unsigned long _beginthread( void( __cdecl *start_address )( void * ), unsigned stack_size, void *arglist );
unsigned long _beginthreadex( void *security, unsigned stack_size, unsigned ( __stdcall *start_address )( void * ), void *arglist, unsigned initflag, unsigned *thrdaddr );
Routine
Required Header
Optional Headers
Compatibility
_beginthread
<process.h>
Win<EFBFBD>95, Win<69>NT
_beginthreadex
<process.h>
Win<EFBFBD>95, Win<69>NT
For additional compatibility information, see Compatibility in the Introduction.
Libraries
LIBCMT.LIB
Multithread static library, retail version
MSVCRT.LIB
Import library for MSVCRTx0.DLL, retail version
MSVCRTx0.DLL
Multithread DLL library, retail version
To use _beginthread or _beginthreadex, the application must link with one of the multithreaded C run-time libraries.
Return Value
If successful, each of these functions returns a handle to the newly created thread. _beginthread returns <20>1 on an error, in which case errno is set to EAGAIN if there are too many threads, or to EINVAL if the argument is invalid or the stack size is incorrect. _beginthreadex returns 0 on an error, in which case errno and doserrno are set.
Parameters
start_address Start address of routine that begins execution of new thread
stack_size Stack size for new thread or 0
arglist Argument list to be passed to new thread or NULL
security Security descriptor for new thread; must be NULL for Windows<77>95 applications
initflag Initial state of new thread (running or suspended)
thrdaddr Address of new thread
_CRTIMP unsigned long __cdecl _beginthreadex(void *, unsigned,
unsigned (__stdcall *) (void *), void *, unsigned, unsigned *);
inline
BOOL Event::isOkay(void)const
{
// return mhEvent?TRUE:FALSE;
return (mhEvent&&WAIT_TIMEOUT==::WaitForSingleObject(mhEvent,0));
}
WORD Event::waitEvent(DWORD timeOut,WORD alertable)const
{
DWORD waitResult;
// if(!mhEvent)return FALSE;
if(!isOkay())return FALSE;
waitResult=::WaitForSingleObjectEx(mhEvent,timeOut,alertable);
if(WAIT_ABANDONED==waitResult)return FALSE;
else if(WAIT_TIMEOUT==waitResult)return FALSE;
else if(WAIT_OBJECT_0==waitResult)return TRUE;
else return TRUE;
}
WORD Event::closeEvent(void)
{
// if(!mhEvent)return FALSE;
if(!isOkay())return FALSE;
::CloseHandle(mhEvent);
mhEvent=0;
return TRUE;
}
CallbackData::ReturnType TabPage::keyDownHandler(CallbackData &someCallbackData)
{
GlobalDefs::outDebug("TabPage::keyDownHandler");
KeyData keyData(someCallbackData);
if(keyData.controlKeyPressed()&&Home==keyData.virtualKey())
{
clearUpdate();
mCurrEntryIndex=0;
showCurrent();
}
else if(keyData.controlKeyPressed()&&End==keyData.virtualKey())
{
clearUpdate();
mCurrEntryIndex=mTabEntries.size()-1;
showCurrent();
}
else if(RightArrow==keyData.virtualKey())
{
if(mCurrEntryIndex+1<mTabEntries.size())
{
mCurrEntryIndex++;
clearUpdate();
showCurrent();
TabEntry &entry=mTabEntries[mCurrEntryIndex];
entry.play(mMIDIDevice->getDevice(),false);
}
else ::MessageBeep(0);
}
else if(LeftArrow==keyData.virtualKey())
{
if(mCurrEntryIndex-1>=0)
{
mCurrEntryIndex--;
clearUpdate();
showCurrent();
TabEntry &entry=mTabEntries[mCurrEntryIndex];
entry.play(mMIDIDevice->getDevice(),false);
}
else ::MessageBeep(0);
}
else if(DownArrow==keyData.virtualKey())
{
if(mCurrEntryIndex+mItemsPerTab+1>=mTabEntries.size())mCurrEntryIndex=mTabEntries.size()-1;
else mCurrEntryIndex+=(mItemsPerTab+1);
clearUpdate();
showCurrent();
TabEntry &entry=mTabEntries[mCurrEntryIndex];
entry.play(mMIDIDevice->getDevice(),false);
}
else if(UpArrow==keyData.virtualKey())
{
if(mCurrEntryIndex-(mItemsPerTab+1)<0)mCurrEntryIndex=0;
else mCurrEntryIndex-=(mItemsPerTab+1);
clearUpdate();
showCurrent();
TabEntry &entry=mTabEntries[mCurrEntryIndex];
entry.play(mMIDIDevice->getDevice(),false);
}
else if(!keyData.shiftKeyPressed()&&Delete==keyData.virtualKey())
{
cut();
}
else if(!keyData.shiftKeyPressed()&&Insert==keyData.virtualKey()) // insert after current position
{
Rect outlineRect;
TabEntry entry;
GDIPoint cursorPos;
clearUpdate();
if(!mTabEntries.size())
{
mTabEntries.insert(&entry);
mCurrEntryIndex=0;
}
else
{
mTabEntries.insertAfter(mCurrEntryIndex,&entry);
mCurrEntryIndex++;
}
if(!getFretEntry())
{
mTabEntries.remove(mCurrEntryIndex);
mCurrEntryIndex--; // smk
if(mCurrEntryIndex>=mTabEntries.size())mCurrEntryIndex=mTabEntries.size()-1;
}
getOutlineRect(mCurrEntryIndex,outlineRect);
mParent->clientToScreen(outlineRect);
cursorPos.x(outlineRect.left());
cursorPos.y(outlineRect.top());
::SetCursorPos(cursorPos.x(),cursorPos.y());
/* Rect outlineRect;
GDIPoint cursorPos;
::GetCursorPos(&cursorPos.getPOINT());
clearUpdate();
mTabEntries.insert(&TabEntry());
mCurrEntryIndex=mTabEntries.size()-1;
if(!getFretEntry())
{
mTabEntries.remove(mCurrEntryIndex);
if(mCurrEntryIndex>=mTabEntries.size())mCurrEntryIndex=mTabEntries.size()-1;
}
clearUpdate();
showCurrent();
getOutlineRect(mCurrEntryIndex,outlineRect);
mParent->clientToScreen(outlineRect);
cursorPos.x(outlineRect.left());
::SetCursorPos(cursorPos.x(),cursorPos.y()); */
}
else if(keyData.shiftKeyPressed()&&Insert==keyData.virtualKey()) // insert at end
{
Rect outlineRect;
GDIPoint cursorPos;
// ::GetCursorPos(&cursorPos.getPOINT());
clearUpdate();
mTabEntries.insert(&TabEntry());
mCurrEntryIndex=mTabEntries.size()-1;
if(!getFretEntry())
{
mCurrEntryIndex--;
mTabEntries.remove(mCurrEntryIndex);
if(mCurrEntryIndex>=mTabEntries.size())mCurrEntryIndex=mTabEntries.size()-1;
}
clearUpdate();
showCurrent();
getOutlineRect(mCurrEntryIndex,outlineRect);
mParent->clientToScreen(outlineRect);
cursorPos.x(outlineRect.left());
cursorPos.y(outlineRect.top());
::SetCursorPos(cursorPos.x(),cursorPos.y());
/* Rect outlineRect;
TabEntry entry;
GDIPoint cursorPos;
::GetCursorPos(&cursorPos.getPOINT());
clearUpdate();
if(!mTabEntries.size())
{
mTabEntries.insert(&entry);
mCurrEntryIndex=0;
}
else
{
mTabEntries.insertAfter(mCurrEntryIndex,&entry);
mCurrEntryIndex++;
}
if(!getFretEntry())
{
mTabEntries.remove(mCurrEntryIndex);
if(mCurrEntryIndex>=mTabEntries.size())mCurrEntryIndex=mTabEntries.size()-1;
}
getOutlineRect(mCurrEntryIndex,outlineRect);
mParent->clientToScreen(outlineRect);
cursorPos.x(outlineRect.left());
::SetCursorPos(cursorPos.x(),cursorPos.y()); */
}
GlobalDefs::outDebug(String("Key Code=")+String().fromInt(keyData.virtualKey()));
return false;
}
else if(keyData.shiftKeyPressed()&&Insert==keyData.virtualKey()) // insert at end
{
Rect outlineRect;
GDIPoint cursorPos;
// ::GetCursorPos(&cursorPos.getPOINT());
clearUpdate();
mTabEntries.insert(&TabEntry());
mCurrEntryIndex=mTabEntries.size()-1;
if(!getFretEntry())
{
mCurrEntryIndex--;
mTabEntries.remove(mCurrEntryIndex);
if(mCurrEntryIndex>=mTabEntries.size())mCurrEntryIndex=mTabEntries.size()-1;
}
clearUpdate();
showCurrent();
getOutlineRect(mCurrEntryIndex,outlineRect);
mParent->clientToScreen(outlineRect);
cursorPos.x(outlineRect.left());
cursorPos.y(outlineRect.top());
::SetCursorPos(cursorPos.x(),cursorPos.y());
/* Rect outlineRect;
TabEntry entry;
GDIPoint cursorPos;
::GetCursorPos(&cursorPos.getPOINT());
clearUpdate();
if(!mTabEntries.size())
{
mTabEntries.insert(&entry);
mCurrEntryIndex=0;
}
else
{
mTabEntries.insertAfter(mCurrEntryIndex,&entry);
mCurrEntryIndex++;
}
if(!getFretEntry())
{
mTabEntries.remove(mCurrEntryIndex);
if(mCurrEntryIndex>=mTabEntries.size())mCurrEntryIndex=mTabEntries.size()-1;
}
getOutlineRect(mCurrEntryIndex,outlineRect);
mParent->clientToScreen(outlineRect);
cursorPos.x(outlineRect.left());
::SetCursorPos(cursorPos.x(),cursorPos.y()); */
}

16
thread/STDTMPL.CPP Normal file
View File

@@ -0,0 +1,16 @@
#ifndef _MSC_VER
#define _EXPAND_BLOCK_TEMPLATES_
#include <common/block.hpp>
#include <common/block.tpp>
#include <common/pvector.hpp>
#include <common/pvector.tpp>
#include <common/pointer.hpp>
#include <common/string.hpp>
#include <thread/thmsg.hpp>
#include <thread/tcallbck.hpp>
#include <thread/tcallbck.tpp>
typedef Block<ThreadMessage> a;
typedef Block<ThreadCallbackPointer> b;
typedef Block<String> c;
#endif

93
thread/TCALLBCK.HPP Normal file
View File

@@ -0,0 +1,93 @@
#ifndef _THREAD_THREADCALLBACK_HPP_
#define _THREAD_THREADCALLBACK_HPP_
#ifndef _THREAD_THREADMESSAGE_HPP_
#include <thread/thmsg.hpp>
#endif
#ifndef _THREAD_PURETHREADCALLBACK_HPP_
#include <thread/ptcllbck.hpp>
#endif
#ifndef _MSC_VER
#ifdef _EXPAND_THREAD_TEMPLATES_
#pragma option -Jgd
#endif
#endif
class ThreadCallbackPointer
{
public:
ThreadCallbackPointer(void);
ThreadCallbackPointer(PureThreadCallback *lpCallback);
ThreadCallbackPointer(const ThreadCallbackPointer &someThreadCallbackPointer);
virtual ~ThreadCallbackPointer();
void operator=(ThreadCallbackPointer &someThreadCallbackPointer);
WORD operator==(const ThreadCallbackPointer &someThreadCallbackPointer)const;
DWORD callback(ThreadMessage &someThreadMessage);
private:
PureThreadCallback *mlpCallback;
};
inline
ThreadCallbackPointer::ThreadCallbackPointer(void)
: mlpCallback(0)
{
}
inline
ThreadCallbackPointer::ThreadCallbackPointer(PureThreadCallback *lpCallback)
: mlpCallback(lpCallback)
{
}
inline
ThreadCallbackPointer::ThreadCallbackPointer(const ThreadCallbackPointer &someThreadCallbackPointer)
: mlpCallback(someThreadCallbackPointer.mlpCallback)
{
}
inline
ThreadCallbackPointer::~ThreadCallbackPointer()
{
}
inline
void ThreadCallbackPointer::operator=(ThreadCallbackPointer &someThreadCallbackPointer)
{
mlpCallback=someThreadCallbackPointer.mlpCallback;
}
inline
WORD ThreadCallbackPointer::operator==(const ThreadCallbackPointer &someThreadCallbackPointer)const
{
return (mlpCallback==someThreadCallbackPointer.mlpCallback);
}
inline
DWORD ThreadCallbackPointer::callback(ThreadMessage &someThreadMessage)
{
if(!mlpCallback)return FALSE;
return mlpCallback->operator*(someThreadMessage);
}
template <class T>
class ThreadCallback : public PureThreadCallback
{
public:
typedef DWORD (T::*LPFNMETHOD)(ThreadMessage &someThreadMessage);
ThreadCallback(void);
ThreadCallback(const ThreadCallback<T> &someThreadCallback);
ThreadCallback(T *lpObject,LPFNMETHOD lpMethod);
virtual ~ThreadCallback();
void setObject(T *lpObject);
void setMethod(LPFNMETHOD lpMethod);
void setCallback(T *lpObject,LPFNMETHOD lpMethod);
WORD operator==(const ThreadCallback<T> &someThreadCallback)const;
void operator=(const ThreadCallback<T> &someThreadCallback);
DWORD operator*(ThreadMessage &someThreadMessage);
private:
T *mlpObject;
DWORD (T::*mlpMethod)(ThreadMessage &someThreadMessage);
};
#if defined(_MSC_VER)
#include <thread/tcallbck.tpp>
#endif
#endif

74
thread/TCALLBCK.TPP Normal file
View File

@@ -0,0 +1,74 @@
#ifndef _THREAD_THREADCALLBACK_HPP_
#error TCALLBCK.HPP MUST PRECEDE TCALLBCK.TPP
#endif
template <class T>
ThreadCallback<T>::ThreadCallback(void)
: mlpObject(0), mlpMethod(0)
{
}
template <class T>
ThreadCallback<T>::ThreadCallback(const ThreadCallback<T> &someThreadCallback)
: mlpObject(someThreadCallback.mlpObject), mlpMethod(someThreadCallback.mlpMethod)
{
}
template <class T>
ThreadCallback<T>::ThreadCallback(T *lpObject,LPFNMETHOD lpMethod)
: mlpObject(lpObject), mlpMethod(lpMethod)
{
}
template <class T>
ThreadCallback<T>::~ThreadCallback()
{
}
template <class T>
WORD ThreadCallback<T>::operator==(const ThreadCallback<T> &someThreadCallback)const
{
return (mlpObject==someThreadCallback.mlpObject && mlpMethod==someThreadCallback.mlpMethod);
}
template <class T>
void ThreadCallback<T>::operator=(const ThreadCallback<T> &someThreadCallback)
{
mlpObject=someThreadCallback.mlpObject;
mlpMethod=someThreadCallback.mlpMethod;
}
template <class T>
void ThreadCallback<T>::setObject(T *lpObject)
{
mlpObject=lpObject;
}
template <class T>
void ThreadCallback<T>::setMethod(LPFNMETHOD lpMethod)
{
mlpMethod=lpMethod;
}
template <class T>
void ThreadCallback<T>::setCallback(T *lpObject,LPFNMETHOD lpMethod)
{
mlpObject=lpObject;
mlpMethod=lpMethod;
}
#if defined(_MSC_VER)
template <class T>
DWORD ThreadCallback<T>::operator*(ThreadMessage &someThreadMessage)
{
DWORD (T::*lpMethod)(ThreadMessage &someThreadMessage)=0;
if((lpMethod==mlpMethod)||!mlpObject)return 0L;
return (mlpObject->*mlpMethod)(someThreadMessage);
}
#else
template <class T>
DWORD ThreadCallback<T>::operator*(ThreadMessage &someThreadMessage)
{
if(!mlpObject||!mlpMethod)return 0L;
return (mlpObject->*mlpMethod)(someThreadMessage);
}
#endif

BIN
thread/TDCONFIG.TDW Normal file

Binary file not shown.

BIN
thread/TDW.TRW Normal file

Binary file not shown.

138
thread/THMSG.HPP Normal file
View File

@@ -0,0 +1,138 @@
#ifndef _THREAD_THREADMESSAGE_HPP_
#define _THREAD_THREADMESSAGE_HPP_
#ifndef _COMMON_WINDOWS_HPP_
#include <common/windows.hpp>
#endif
#ifndef _COMMON_SYSTEMTIME_HPP_
#include <common/systime.hpp>
#endif
class ThreadMessage
{
public:
enum TMMsg{TM_VOID,TM_CREATE,TM_DESTROY,TM_USER};
enum TMPriority{PriorityLow,PriorityNormal,PriorityHigh};
ThreadMessage(void);
ThreadMessage(TMMsg message,DWORD userDataOne=0L,DWORD userDataTwo=0L,TMPriority priority=PriorityNormal);
ThreadMessage(const ThreadMessage &someThreadMessage);
virtual ~ThreadMessage();
ThreadMessage &operator=(const ThreadMessage &someThreadMessage);
WORD operator==(const ThreadMessage &someThreadMessage)const;
TMMsg message(void)const;
void message(TMMsg message);
DWORD userDataOne(void)const;
void userDataOne(DWORD userDataOne);
DWORD userDataTwo(void)const;
void userDataTwo(DWORD userDataTwo);
TMPriority priority(void)const;
void priority(TMPriority priority);
SystemTime &messageTime(void);
void messageTime(const SystemTime &messageTime);
private:
TMMsg mMessage;
TMPriority mPriority;
SystemTime mMessageTime;
DWORD mUserDataOne;
DWORD mUserDataTwo;
};
inline
ThreadMessage::ThreadMessage(void)
: mMessage(TM_VOID), mUserDataOne(0L), mUserDataTwo(0L), mPriority(PriorityNormal)
{
}
inline
ThreadMessage::ThreadMessage(TMMsg message,DWORD userDataOne,DWORD userDataTwo,TMPriority priority)
: mMessage(message), mUserDataOne(userDataOne), mUserDataTwo(userDataTwo),
mPriority(priority)
{
}
inline
ThreadMessage::ThreadMessage(const ThreadMessage &someThreadMessage)
{
*this=someThreadMessage;
}
inline
ThreadMessage::~ThreadMessage()
{
}
inline
ThreadMessage &ThreadMessage::operator=(const ThreadMessage &someThreadMessage)
{
message(someThreadMessage.message());
userDataOne(someThreadMessage.userDataOne());
userDataTwo(someThreadMessage.userDataTwo());
priority(someThreadMessage.priority());
return *this;
}
inline
WORD ThreadMessage::operator==(const ThreadMessage &someThreadMessage)const
{
return message()==someThreadMessage.message();
}
inline
ThreadMessage::TMMsg ThreadMessage::message(void)const
{
return mMessage;
}
inline
void ThreadMessage::message(TMMsg message)
{
mMessage=message;
}
inline
DWORD ThreadMessage::userDataOne(void)const
{
return mUserDataOne;
}
inline
void ThreadMessage::userDataOne(DWORD userDataOne)
{
mUserDataOne=userDataOne;
}
inline
DWORD ThreadMessage::userDataTwo(void)const
{
return mUserDataTwo;
}
inline
void ThreadMessage::userDataTwo(DWORD userDataTwo)
{
mUserDataTwo=userDataTwo;
}
inline
ThreadMessage::TMPriority ThreadMessage::priority(void)const
{
return mPriority;
}
inline
void ThreadMessage::priority(TMPriority priority)
{
mPriority=priority;
}
inline
SystemTime &ThreadMessage::messageTime(void)
{
return mMessageTime;
}
inline
void ThreadMessage::messageTime(const SystemTime &messageTime)
{
mMessageTime=messageTime;
}
#endif

30
thread/THREAD.BAK Normal file
View File

@@ -0,0 +1,30 @@
#include <thread/thread.hpp>
WORD PureThread::start(LPVOID lpCreationData)
{
if(isOkay()||!mlpfnThreadProc)return FALSE;
mhThread=::CreateThread((SECURITY_ATTRIBUTES*)0,InitialStack,mlpfnThreadProc,lpCreationData,CREATE_SUSPENDED,&mThreadID);
if(!mhThread)return FALSE;
mThreadStatus=InSuspend;
return TRUE;
}
WORD PureThread::fatalThreadExit(void)
{
WORD returnCode(FALSE);
if(!isOkay())return returnCode;
returnCode=::TerminateThread(mhThread,exitCode());
mThreadStatus=InStop;mhThread=0;mThreadID=0;
return returnCode;
}
DWORD PureThread::exitCode(void)const
{
DWORD exitCodeThread(0L);
if(!isOkay())return exitCodeThread;
::GetExitCodeThread(mhThread,&exitCodeThread);
return exitCodeThread;
}

41
thread/THREAD.CPP Normal file
View File

@@ -0,0 +1,41 @@
#include <thread/thread.hpp>
WORD PureThread::start(LPVOID lpCreationData)
{
if(isOkay()||!mlpfnThreadProc)return FALSE;
mhThread=::CreateThread((SECURITY_ATTRIBUTES*)0,InitialStack,mlpfnThreadProc,lpCreationData,CREATE_SUSPENDED,&mThreadID);
if(!mhThread)return FALSE;
mThreadStatus=InSuspend;
return TRUE;
}
WORD PureThread::fatalThreadExit(void)
{
WORD returnCode(FALSE);
if(!isOkay())return returnCode;
returnCode=::TerminateThread(mhThread,exitCode());
mThreadStatus=InStop;mhThread=0;mThreadID=0;
return returnCode;
}
DWORD PureThread::exitCode(void)const
{
DWORD exitCodeThread(0L);
if(!isOkay())return exitCodeThread;
::GetExitCodeThread(mhThread,&exitCodeThread);
return exitCodeThread;
}
PureThread::ThreadPriority PureThread::getThreadPriority(void)const
{
if(!isOkay())return ThreadPriorityNormal;
return ThreadPriority(::GetThreadPriority(mhThread));
}
PureThread::ThreadPriority PureThread::setThreadPriority(ThreadPriority threadPriority)const
{
if(!isOkay())return ThreadPriorityNormal;
return ThreadPriority(::SetThreadPriority(mhThread,(int)threadPriority));
}

106
thread/THREAD.HPP Normal file
View File

@@ -0,0 +1,106 @@
#ifndef _THREAD_PURETHREAD_HPP_
#define _THREAD_PURETHREAD_HPP_
#ifndef _COMMON_WINDOWS_HPP_
#include <common/windows.hpp>
#endif
#ifndef _THREAD_CONTEXT_HPP_
#include <thread/context.hpp>
#endif
class PureThread
{
public:
typedef DWORD (WINAPI *LPFNTHREADPROC)(LPVOID lpInstanceData);
enum Status{InSuspend,InTerminate,InRun,InStop,InNothing};
enum ThreadPriority{ThreadPriorityAboveNormal=THREAD_PRIORITY_ABOVE_NORMAL,
ThreadPriorityBelowNormal=THREAD_PRIORITY_BELOW_NORMAL,
ThreadPriorityHighest=THREAD_PRIORITY_HIGHEST,
ThreadPriorityIdle=THREAD_PRIORITY_IDLE,
ThreadPriorityLowest=THREAD_PRIORITY_LOWEST,
ThreadPriorityNormal=THREAD_PRIORITY_NORMAL,
ThreadPriorityTimeCritical=THREAD_PRIORITY_TIME_CRITICAL};
PureThread(HANDLE hThread=GetCurrentThread());
PureThread(LPFNTHREADPROC lpfnThreadProc);
virtual ~PureThread();
WORD start(LPVOID lpCreationData=0);
WORD fatalThreadExit(void);
DWORD wait(DWORD timeout=INFINITE,bool alertable=false)const;
DWORD resume(void);
DWORD suspend(void);
DWORD exitCode(void)const;
WORD context(Context &contextThread)const;
ThreadPriority getThreadPriority(void)const;
ThreadPriority setThreadPriority(ThreadPriority threadPriority)const;
WORD isOkay(void)const;
String getThreadName(void)const;
private:
enum{InitialStack=8192};
PureThread &operator=(const PureThread &somePureThread);
HANDLE mhThread;
DWORD mThreadID;
LPFNTHREADPROC mlpfnThreadProc;
Status mThreadStatus;
};
inline
PureThread::PureThread(HANDLE hThread)
: mhThread(hThread), mThreadID(0), mlpfnThreadProc(0), mThreadStatus(InRun)
{
}
inline
PureThread::PureThread(LPFNTHREADPROC lpfnThreadProc)
: mhThread(0), mThreadID(0), mlpfnThreadProc(lpfnThreadProc), mThreadStatus(InNothing)
{
}
inline
PureThread::~PureThread()
{
}
inline
DWORD PureThread::suspend(void)
{
if(!isOkay()||InRun!=mThreadStatus)return FALSE;
mThreadStatus=InSuspend;
return ::SuspendThread(mhThread);
}
inline
DWORD PureThread::resume(void)
{
if(!isOkay()||InSuspend!=mThreadStatus)return FALSE;
mThreadStatus=InRun;
return ::ResumeThread(mhThread);
}
inline
DWORD PureThread::wait(DWORD timeout,bool alertable)const
{
if(!isOkay()||InRun!=mThreadStatus)return WAIT_ABANDONED;
return ::WaitForSingleObjectEx(mhThread,timeout,alertable);
}
inline
WORD PureThread::context(Context &contextThread)const
{
if(!isOkay())return FALSE;
return contextThread.getThreadContext(mhThread);
}
inline
WORD PureThread::isOkay(void)const
{
return (0==mhThread?FALSE:TRUE);
}
inline
String PureThread::getThreadName(void)const
{
String strThreadName;
::sprintf(strThreadName.str(),"%08lx",mThreadID);
return strThreadName;
}
#endif

16
thread/THREAD.PLG Normal file
View File

@@ -0,0 +1,16 @@
<html>
<body>
<pre>
<h1>Build Log</h1>
<h3>
--------------------Configuration: thread - Win32 Debug--------------------
</h3>
<h3>Command Lines</h3>
<h3>Results</h3>
msthread.lib - 0 error(s), 0 warning(s)
</pre>
</body>
</html>

BIN
thread/THREAD32.IDE Normal file

Binary file not shown.

BIN
thread/THREAD32.~DE Normal file

Binary file not shown.

81
thread/THTIMER.CPP Normal file
View File

@@ -0,0 +1,81 @@
#include <thread/thtimer.hpp>
ThreadTimer::ThreadTimer(void)
: mMinResolution(0), mIsOkay(FALSE), mHasTimedEvent(FALSE), mTimerID(0), mIsFirstBreak(TRUE)
{
if(::timeGetDevCaps(&mTimerCapability,sizeof(TIMECAPS)))return;
mMinResolution=mTimerCapability.wPeriodMin;
if(::timeBeginPeriod(mMinResolution))return;
mIsOkay=TRUE;
}
ThreadTimer::ThreadTimer(WORD minResolution)
: mMinResolution(minResolution), mIsOkay(FALSE), mHasTimedEvent(FALSE), mTimerID(0), mIsFirstBreak(TRUE)
{
if(::timeGetDevCaps(&mTimerCapability,sizeof(TIMECAPS)))return;
if(mMinResolution<mTimerCapability.wPeriodMin)mMinResolution=mTimerCapability.wPeriodMin;
if(::timeBeginPeriod(mMinResolution))return;
mIsOkay=TRUE;
}
ThreadTimer::~ThreadTimer()
{
if(mIsOkay){stopTimer();::timeEndPeriod(mMinResolution);}
mTimerMutex.requestMutex();
mTimerMutex.releaseMutex();
}
WORD ThreadTimer::startTimer(UINT deltaTime)
{
if(!mIsOkay)return FALSE;
if(mHasTimedEvent)return FALSE;
isFirstBreak(TRUE);
if(0==(mTimerID=::timeSetEvent(deltaTime,mMinResolution,(LPTIMECALLBACK)timerProc,(DWORD)this,TIME_PERIODIC)))return FALSE;
mHasTimedEvent=TRUE;
return TRUE;
}
WORD ThreadTimer::stopTimer(void)
{
WORD returnCode(FALSE);
if(!mIsOkay)return returnCode;
if(!mHasTimedEvent)return returnCode;
if(!::timeKillEvent(mTimerID))returnCode=TRUE;
isFirstBreak(FALSE);
mHasTimedEvent=FALSE;
mTimerID=FALSE;
return returnCode;
}
void CALLBACK ThreadTimer::timerProc(UINT /*wTimerID*/,UINT /*mMsg*/,DWORD dwUser,DWORD /*dummyOne*/,DWORD /*dummyTwo*/)
{
CallbackData callbackData;
if(!((ThreadTimer*)dwUser))return;
((ThreadTimer*)dwUser)->mTimerMutex.requestMutex();
if(((ThreadTimer*)dwUser)->isFirstBreak())
{
((ThreadTimer*)dwUser)->isFirstBreak(FALSE);
((ThreadTimer*)dwUser)->timerStarted();
}
if(((CallbackData::ReturnType)FALSE)==((ThreadTimer*)dwUser)->mCallbackPointer.callback(callbackData))
{
((ThreadTimer*)dwUser)->timerStopped();
((ThreadTimer*)dwUser)->stopTimer();
}
((ThreadTimer*)dwUser)->mTimerMutex.releaseMutex();
return;
}
// virtuals
void ThreadTimer::timerStarted(void)
{
return;
}
void ThreadTimer::timerStopped(void)
{
return;
}

81
thread/THTIMER.HPP Normal file
View File

@@ -0,0 +1,81 @@
#ifndef _THREAD_THREADTIMER_HPP_
#define _COMMON_THREADTIMER_HPP_
#ifndef _COMMON_WINDOWS_HPP_
#include <common/windows.hpp>
#endif
#ifndef _COMMON_CALLBACK_HPP_
#include <common/callback.hpp>
#endif
#ifndef _COMMON_MMSYSTEM_HPP_
#include <common/mmsystem.hpp>
#endif
#ifndef _THREAD_MUTEX_HPP_
#include <thread/mutex.hpp>
#endif
class ThreadTimer
{
public:
ThreadTimer(void);
ThreadTimer(WORD minResolution);
virtual ~ThreadTimer();
DWORD getSystemTime(void)const;
WORD startTimer(UINT deltaTime);
WORD stopTimer(void);
WORD isRunning(void)const;
void insertHandler(PureCallback *lpCallback);
void removeHandler(void);
protected:
virtual void timerStarted(void);
virtual void timerStopped(void);
private:
static void CALLBACK timerProc(UINT wTimerID,UINT mMsg,DWORD dwUser,DWORD dummyOne,DWORD dummyTwo);
WORD isFirstBreak(void)const;
void isFirstBreak(WORD isFirstBreak);
TIMECAPS mTimerCapability;
WORD mMinResolution;
WORD mIsOkay;
WORD mHasTimedEvent;
WORD mIsFirstBreak;
UINT mTimerID;
Mutex mTimerMutex;
CallbackPointer mCallbackPointer;
};
inline
DWORD ThreadTimer::getSystemTime(void)const
{
return ::timeGetTime();
}
inline
WORD ThreadTimer::isRunning(void)const
{
return mHasTimedEvent;
}
inline
void ThreadTimer::insertHandler(PureCallback *lpCallback)
{
mCallbackPointer=CallbackPointer(lpCallback);
}
inline
void ThreadTimer::removeHandler(void)
{
mCallbackPointer=CallbackPointer();
}
inline
WORD ThreadTimer::isFirstBreak(void)const
{
return mIsFirstBreak;
}
inline
void ThreadTimer::isFirstBreak(WORD isFirstBreak)
{
mIsFirstBreak=isFirstBreak;
}
#endif

456
thread/Thread.mak Normal file
View File

@@ -0,0 +1,456 @@
# Microsoft Developer Studio Generated NMAKE File, Format Version 4.20
# ** DO NOT EDIT **
# TARGTYPE "Win32 (x86) Static Library" 0x0104
!IF "$(CFG)" == ""
CFG=thread - Win32 Debug
!MESSAGE No configuration specified. Defaulting to thread - Win32 Debug.
!ENDIF
!IF "$(CFG)" != "thread - Win32 Release" && "$(CFG)" != "thread - Win32 Debug"
!MESSAGE Invalid configuration "$(CFG)" specified.
!MESSAGE You can specify a configuration when running NMAKE on this makefile
!MESSAGE by defining the macro CFG on the command line. For example:
!MESSAGE
!MESSAGE NMAKE /f "Thread.mak" CFG="thread - Win32 Debug"
!MESSAGE
!MESSAGE Possible choices for configuration are:
!MESSAGE
!MESSAGE "thread - Win32 Release" (based on "Win32 (x86) Static Library")
!MESSAGE "thread - Win32 Debug" (based on "Win32 (x86) Static Library")
!MESSAGE
!ERROR An invalid configuration is specified.
!ENDIF
!IF "$(OS)" == "Windows_NT"
NULL=
!ELSE
NULL=nul
!ENDIF
################################################################################
# Begin Project
# PROP Target_Last_Scanned "thread - Win32 Debug"
CPP=cl.exe
!IF "$(CFG)" == "thread - Win32 Release"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 0
# PROP BASE Output_Dir "Release"
# PROP BASE Intermediate_Dir "Release"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 0
# PROP Output_Dir "Release"
# PROP Intermediate_Dir "Release"
# PROP Target_Dir ""
OUTDIR=.\Release
INTDIR=.\Release
ALL : "$(OUTDIR)\Thread.lib"
CLEAN :
-@erase "$(INTDIR)\Event.obj"
-@erase "$(INTDIR)\Msgqueue.obj"
-@erase "$(INTDIR)\Mthread.obj"
-@erase "$(INTDIR)\Mutex.obj"
-@erase "$(INTDIR)\Ptcllbck.obj"
-@erase "$(INTDIR)\Qthread.obj"
-@erase "$(INTDIR)\Stdtmpl.obj"
-@erase "$(INTDIR)\Thread.obj"
-@erase "$(INTDIR)\thtimer.obj"
-@erase "$(OUTDIR)\Thread.lib"
"$(OUTDIR)" :
if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /c
# ADD CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /c
CPP_PROJ=/nologo /ML /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS"\
/Fp"$(INTDIR)/Thread.pch" /YX /Fo"$(INTDIR)/" /c
CPP_OBJS=.\Release/
CPP_SBRS=.\.
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
BSC32_FLAGS=/nologo /o"$(OUTDIR)/Thread.bsc"
BSC32_SBRS= \
LIB32=link.exe -lib
# ADD BASE LIB32 /nologo
# ADD LIB32 /nologo
LIB32_FLAGS=/nologo /out:"$(OUTDIR)/Thread.lib"
LIB32_OBJS= \
"$(INTDIR)\Event.obj" \
"$(INTDIR)\Msgqueue.obj" \
"$(INTDIR)\Mthread.obj" \
"$(INTDIR)\Mutex.obj" \
"$(INTDIR)\Ptcllbck.obj" \
"$(INTDIR)\Qthread.obj" \
"$(INTDIR)\Stdtmpl.obj" \
"$(INTDIR)\Thread.obj" \
"$(INTDIR)\thtimer.obj"
"$(OUTDIR)\Thread.lib" : "$(OUTDIR)" $(DEF_FILE) $(LIB32_OBJS)
$(LIB32) @<<
$(LIB32_FLAGS) $(DEF_FLAGS) $(LIB32_OBJS)
<<
!ELSEIF "$(CFG)" == "thread - Win32 Debug"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 1
# PROP BASE Output_Dir "Debug"
# PROP BASE Intermediate_Dir "Debug"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 1
# PROP Output_Dir "msvcobj"
# PROP Intermediate_Dir "msvcobj"
# PROP Target_Dir ""
OUTDIR=.\msvcobj
INTDIR=.\msvcobj
ALL : "..\exe\msthread.lib"
CLEAN :
-@erase "$(INTDIR)\Event.obj"
-@erase "$(INTDIR)\Msgqueue.obj"
-@erase "$(INTDIR)\Mthread.obj"
-@erase "$(INTDIR)\Mutex.obj"
-@erase "$(INTDIR)\Ptcllbck.obj"
-@erase "$(INTDIR)\Qthread.obj"
-@erase "$(INTDIR)\Stdtmpl.obj"
-@erase "$(INTDIR)\Thread.obj"
-@erase "$(INTDIR)\thtimer.obj"
-@erase "..\exe\msthread.lib"
"$(OUTDIR)" :
if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
# ADD BASE CPP /nologo /W3 /GX /Z7 /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /c
# ADD CPP /nologo /Zp1 /MTd /Z7 /O2 /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "__FLAT__" /D "STRICT" /Fp"..\exe\msvc42.pch" /YX"windows.h" /c
CPP_PROJ=/nologo /Zp1 /MTd /Z7 /O2 /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D\
"__FLAT__" /D "STRICT" /Fp"..\exe\msvc42.pch" /YX"windows.h" /Fo"$(INTDIR)/" /c\
CPP_OBJS=.\msvcobj/
CPP_SBRS=.\.
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
BSC32_FLAGS=/nologo /o"$(OUTDIR)/Thread.bsc"
BSC32_SBRS= \
LIB32=link.exe -lib
# ADD BASE LIB32 /nologo
# ADD LIB32 /nologo /out:"..\exe\msthread.lib"
LIB32_FLAGS=/nologo /out:"..\exe\msthread.lib"
LIB32_OBJS= \
"$(INTDIR)\Event.obj" \
"$(INTDIR)\Msgqueue.obj" \
"$(INTDIR)\Mthread.obj" \
"$(INTDIR)\Mutex.obj" \
"$(INTDIR)\Ptcllbck.obj" \
"$(INTDIR)\Qthread.obj" \
"$(INTDIR)\Stdtmpl.obj" \
"$(INTDIR)\Thread.obj" \
"$(INTDIR)\thtimer.obj"
"..\exe\msthread.lib" : "$(OUTDIR)" $(DEF_FILE) $(LIB32_OBJS)
$(LIB32) @<<
$(LIB32_FLAGS) $(DEF_FLAGS) $(LIB32_OBJS)
<<
!ENDIF
.c{$(CPP_OBJS)}.obj:
$(CPP) $(CPP_PROJ) $<
.cpp{$(CPP_OBJS)}.obj:
$(CPP) $(CPP_PROJ) $<
.cxx{$(CPP_OBJS)}.obj:
$(CPP) $(CPP_PROJ) $<
.c{$(CPP_SBRS)}.sbr:
$(CPP) $(CPP_PROJ) $<
.cpp{$(CPP_SBRS)}.sbr:
$(CPP) $(CPP_PROJ) $<
.cxx{$(CPP_SBRS)}.sbr:
$(CPP) $(CPP_PROJ) $<
################################################################################
# Begin Target
# Name "thread - Win32 Release"
# Name "thread - Win32 Debug"
!IF "$(CFG)" == "thread - Win32 Release"
!ELSEIF "$(CFG)" == "thread - Win32 Debug"
!ENDIF
################################################################################
# Begin Source File
SOURCE=.\Thread.cpp
DEP_CPP_THREA=\
{$(INCLUDE)}"\.\Context.hpp"\
{$(INCLUDE)}"\.\Savearea.hpp"\
{$(INCLUDE)}"\.\Thread.hpp"\
{$(INCLUDE)}"\Common\Stdlib.hpp"\
{$(INCLUDE)}"\Common\String.hpp"\
{$(INCLUDE)}"\Common\Windows.hpp"\
{$(INCLUDE)}"\Common\Winnt.hpp"\
"$(INTDIR)\Thread.obj" : $(SOURCE) $(DEP_CPP_THREA) "$(INTDIR)"
# End Source File
################################################################################
# Begin Source File
SOURCE=.\Msgqueue.cpp
DEP_CPP_MSGQU=\
{$(INCLUDE)}"\.\Event.hpp"\
{$(INCLUDE)}"\.\Msgqueue.hpp"\
{$(INCLUDE)}"\.\Mutex.hpp"\
{$(INCLUDE)}"\.\Thmsg.hpp"\
{$(INCLUDE)}"\Common\Block.hpp"\
{$(INCLUDE)}"\Common\Block.tpp"\
{$(INCLUDE)}"\Common\except.hpp"\
{$(INCLUDE)}"\Common\Filetime.hpp"\
{$(INCLUDE)}"\Common\Stdio.hpp"\
{$(INCLUDE)}"\Common\Stdlib.hpp"\
{$(INCLUDE)}"\Common\String.hpp"\
{$(INCLUDE)}"\Common\Systime.hpp"\
{$(INCLUDE)}"\Common\Windows.hpp"\
"$(INTDIR)\Msgqueue.obj" : $(SOURCE) $(DEP_CPP_MSGQU) "$(INTDIR)"
# End Source File
################################################################################
# Begin Source File
SOURCE=.\Mthread.cpp
!IF "$(CFG)" == "thread - Win32 Release"
DEP_CPP_MTHRE=\
{$(INCLUDE)}"\.\Context.hpp"\
{$(INCLUDE)}"\.\Event.hpp"\
{$(INCLUDE)}"\.\Msgqueue.hpp"\
{$(INCLUDE)}"\.\Mthread.hpp"\
{$(INCLUDE)}"\.\Mutex.hpp"\
{$(INCLUDE)}"\.\Ptcllbck.hpp"\
{$(INCLUDE)}"\.\Qthread.hpp"\
{$(INCLUDE)}"\.\Savearea.hpp"\
{$(INCLUDE)}"\.\Tcallbck.hpp"\
{$(INCLUDE)}"\.\Tcallbck.tpp"\
{$(INCLUDE)}"\.\Thmsg.hpp"\
{$(INCLUDE)}"\.\Thread.hpp"\
{$(INCLUDE)}"\Common\Block.hpp"\
{$(INCLUDE)}"\Common\Block.tpp"\
{$(INCLUDE)}"\Common\except.hpp"\
{$(INCLUDE)}"\Common\Filetime.hpp"\
{$(INCLUDE)}"\Common\Stdio.hpp"\
{$(INCLUDE)}"\Common\Stdlib.hpp"\
{$(INCLUDE)}"\Common\String.hpp"\
{$(INCLUDE)}"\Common\Systime.hpp"\
{$(INCLUDE)}"\Common\Windows.hpp"\
{$(INCLUDE)}"\Common\Winnt.hpp"\
"$(INTDIR)\Mthread.obj" : $(SOURCE) $(DEP_CPP_MTHRE) "$(INTDIR)"
!ELSEIF "$(CFG)" == "thread - Win32 Debug"
DEP_CPP_MTHRE=\
{$(INCLUDE)}"\.\Mthread.hpp"\
{$(INCLUDE)}"\Common\Block.hpp"\
{$(INCLUDE)}"\Common\Block.tpp"\
{$(INCLUDE)}"\Common\except.hpp"\
{$(INCLUDE)}"\Common\Windows.hpp"\
"$(INTDIR)\Mthread.obj" : $(SOURCE) $(DEP_CPP_MTHRE) "$(INTDIR)"
!ENDIF
# End Source File
################################################################################
# Begin Source File
SOURCE=.\Mutex.cpp
DEP_CPP_MUTEX=\
{$(INCLUDE)}"\.\Mutex.hpp"\
{$(INCLUDE)}"\.\Postfix.hpp"\
{$(INCLUDE)}"\Common\Stdio.hpp"\
{$(INCLUDE)}"\Common\Stdlib.hpp"\
{$(INCLUDE)}"\Common\String.hpp"\
{$(INCLUDE)}"\Common\Windows.hpp"\
"$(INTDIR)\Mutex.obj" : $(SOURCE) $(DEP_CPP_MUTEX) "$(INTDIR)"
# End Source File
################################################################################
# Begin Source File
SOURCE=.\Ptcllbck.cpp
DEP_CPP_PTCLL=\
{$(INCLUDE)}"\.\Ptcllbck.hpp"\
{$(INCLUDE)}"\.\Thmsg.hpp"\
{$(INCLUDE)}"\Common\Filetime.hpp"\
{$(INCLUDE)}"\Common\Stdlib.hpp"\
{$(INCLUDE)}"\Common\String.hpp"\
{$(INCLUDE)}"\Common\Systime.hpp"\
{$(INCLUDE)}"\Common\Windows.hpp"\
"$(INTDIR)\Ptcllbck.obj" : $(SOURCE) $(DEP_CPP_PTCLL) "$(INTDIR)"
# End Source File
################################################################################
# Begin Source File
SOURCE=.\Qthread.cpp
!IF "$(CFG)" == "thread - Win32 Release"
DEP_CPP_QTHRE=\
{$(INCLUDE)}"\.\Context.hpp"\
{$(INCLUDE)}"\.\Event.hpp"\
{$(INCLUDE)}"\.\Msgqueue.hpp"\
{$(INCLUDE)}"\.\Mutex.hpp"\
{$(INCLUDE)}"\.\Qthread.hpp"\
{$(INCLUDE)}"\.\Savearea.hpp"\
{$(INCLUDE)}"\.\Thmsg.hpp"\
{$(INCLUDE)}"\.\Thread.hpp"\
{$(INCLUDE)}"\Common\Block.hpp"\
{$(INCLUDE)}"\Common\Block.tpp"\
{$(INCLUDE)}"\Common\except.hpp"\
{$(INCLUDE)}"\Common\Filetime.hpp"\
{$(INCLUDE)}"\Common\Stdio.hpp"\
{$(INCLUDE)}"\Common\Stdlib.hpp"\
{$(INCLUDE)}"\Common\String.hpp"\
{$(INCLUDE)}"\Common\Systime.hpp"\
{$(INCLUDE)}"\Common\Windows.hpp"\
{$(INCLUDE)}"\Common\Winnt.hpp"\
"$(INTDIR)\Qthread.obj" : $(SOURCE) $(DEP_CPP_QTHRE) "$(INTDIR)"
!ELSEIF "$(CFG)" == "thread - Win32 Debug"
DEP_CPP_QTHRE=\
{$(INCLUDE)}"\.\Context.hpp"\
{$(INCLUDE)}"\.\Event.hpp"\
{$(INCLUDE)}"\.\Msgqueue.hpp"\
{$(INCLUDE)}"\.\Mutex.hpp"\
{$(INCLUDE)}"\.\Qthread.hpp"\
{$(INCLUDE)}"\.\Savearea.hpp"\
{$(INCLUDE)}"\.\Thmsg.hpp"\
{$(INCLUDE)}"\.\Thread.hpp"\
{$(INCLUDE)}"\Common\Filetime.hpp"\
{$(INCLUDE)}"\Common\Stdio.hpp"\
{$(INCLUDE)}"\Common\Stdlib.hpp"\
{$(INCLUDE)}"\Common\String.hpp"\
{$(INCLUDE)}"\Common\Systime.hpp"\
{$(INCLUDE)}"\Common\Windows.hpp"\
{$(INCLUDE)}"\Common\Winnt.hpp"\
"$(INTDIR)\Qthread.obj" : $(SOURCE) $(DEP_CPP_QTHRE) "$(INTDIR)"
!ENDIF
# End Source File
################################################################################
# Begin Source File
SOURCE=.\Stdtmpl.cpp
DEP_CPP_STDTM=\
{$(INCLUDE)}"\.\Ptcllbck.hpp"\
{$(INCLUDE)}"\.\Tcallbck.hpp"\
{$(INCLUDE)}"\.\Tcallbck.tpp"\
{$(INCLUDE)}"\.\Thmsg.hpp"\
{$(INCLUDE)}"\Common\Block.hpp"\
{$(INCLUDE)}"\Common\Block.tpp"\
{$(INCLUDE)}"\Common\except.hpp"\
{$(INCLUDE)}"\Common\Filetime.hpp"\
{$(INCLUDE)}"\Common\Fixup.hpp"\
{$(INCLUDE)}"\Common\Pointer.hpp"\
{$(INCLUDE)}"\Common\Pvector.hpp"\
{$(INCLUDE)}"\Common\Pvector.tpp"\
{$(INCLUDE)}"\Common\Stdlib.hpp"\
{$(INCLUDE)}"\Common\String.hpp"\
{$(INCLUDE)}"\Common\Systime.hpp"\
{$(INCLUDE)}"\Common\Types.hpp"\
{$(INCLUDE)}"\Common\Windows.hpp"\
"$(INTDIR)\Stdtmpl.obj" : $(SOURCE) $(DEP_CPP_STDTM) "$(INTDIR)"
# End Source File
################################################################################
# Begin Source File
SOURCE=.\Event.cpp
DEP_CPP_EVENT=\
{$(INCLUDE)}"\.\Event.hpp"\
{$(INCLUDE)}"\.\Postfix.hpp"\
{$(INCLUDE)}"\Common\Stdio.hpp"\
{$(INCLUDE)}"\Common\Stdlib.hpp"\
{$(INCLUDE)}"\Common\String.hpp"\
{$(INCLUDE)}"\Common\Windows.hpp"\
"$(INTDIR)\Event.obj" : $(SOURCE) $(DEP_CPP_EVENT) "$(INTDIR)"
# End Source File
################################################################################
# Begin Source File
SOURCE=.\thtimer.cpp
DEP_CPP_THTIM=\
{$(INCLUDE)}"\.\Mutex.hpp"\
{$(INCLUDE)}"\.\thtimer.hpp"\
{$(INCLUDE)}"\Common\Callback.hpp"\
{$(INCLUDE)}"\Common\Callback.tpp"\
{$(INCLUDE)}"\Common\Cbdata.hpp"\
{$(INCLUDE)}"\Common\Cbptr.hpp"\
{$(INCLUDE)}"\Common\Gdipoint.hpp"\
{$(INCLUDE)}"\Common\Mmsystem.hpp"\
{$(INCLUDE)}"\Common\Pcallbck.hpp"\
{$(INCLUDE)}"\Common\Point.hpp"\
{$(INCLUDE)}"\Common\Rect.hpp"\
{$(INCLUDE)}"\Common\Stdio.hpp"\
{$(INCLUDE)}"\Common\Stdlib.hpp"\
{$(INCLUDE)}"\Common\String.hpp"\
{$(INCLUDE)}"\Common\Windows.hpp"\
{$(INCLUDE)}"\Common\Windowsx.hpp"\
"$(INTDIR)\thtimer.obj" : $(SOURCE) $(DEP_CPP_THTIM) "$(INTDIR)"
# End Source File
# End Target
# End Project
################################################################################

184
thread/ThreadStorage.hpp Normal file
View File

@@ -0,0 +1,184 @@
#ifndef _THREAD_THREADSTORAGE_HPP_
#define _THREAD_THREADSTORAGE_HPP_
#ifndef _COMMON_WINDOWS_HPP_
#include <common/windows.hpp>
#endif
#ifndef _COMMON_SMARTPOINTER_HPP_
#include <common/pointer.hpp>
#endif
#ifndef _COMMON_PUREDWORD_HPP_
#include <common/puredwrd.hpp>
#endif
#ifndef _BSPTREE_BINARYTREE_HPP_
#include <bsptree/bintree.hpp>
#endif
template <class T>
class ThreadStorage
{
public:
ThreadStorage(void);
ThreadStorage(const ThreadStorage<T> &threadStorage);
virtual ~ThreadStorage();
bool operator==(const ThreadStorage<T> &threadStorage)const;
bool operator<(const ThreadStorage<T> &threadStorage)const;
bool operator>(const ThreadStorage<T> &threadStorage)const;
T &getData(void);
void setData(const T &data);
DWORD getThreadId(void)const;
void setThreadId(DWORD threadId);
private:
T mData;
DWORD mThreadId;
};
template <class T>
inline
ThreadStorage<T>::ThreadStorage(void)
: mThreadId(0)
{
}
template <class T>
inline
ThreadStorage<T>::ThreadStorage(const ThreadStorage<T> &threadStorage)
{
*this=threadStorage;
}
template <class T>
inline
ThreadStorage<T>::~ThreadStorage()
{
}
template <class T>
inline
bool ThreadStorage<T>::operator==(const ThreadStorage<T> &threadStorage)const
{
return mThreadId==threadStorage.mThreadId;
}
template <class T>
inline
bool ThreadStorage<T>::operator<(const ThreadStorage<T> &threadStorage)const
{
return mThreadId<threadStorage.mThreadId;
}
template <class T>
inline
bool ThreadStorage<T>::operator>(const ThreadStorage<T> &threadStorage)const
{
return mThreadId<threadStorage.mThreadId;
}
template <class T>
inline
T &ThreadStorage<T>::getData(void)
{
return mData;
}
template <class T>
inline
void ThreadStorage<T>::setData(const T &data)
{
mData=data;
}
template <class T>
inline
DWORD ThreadStorage<T>::getThreadId(void)const
{
return mThreadId;
}
template <class T>
inline
void ThreadStorage<T>::setThreadId(DWORD threadId)
{
mThreadId=threadId;
}
template <class T>
class ThreadLocalStorage : private BinaryTree<ThreadStorage<T> >
{
public:
ThreadLocalStorage();
bool getThreadData(SmartPointer<T> &threadData);
bool haveThreadData(void);
void removeThreadData(void);
bool addThreadData(const T &data);
private:
ThreadLocalStorage(const ThreadLocalStorage<T> &threadLocalStorage);
ThreadLocalStorage<T> &operator=(const ThreadLocalStorage<T> &threadLocalaStorage);
};
template <class T>
inline
ThreadLocalStorage<T>::ThreadLocalStorage()
{
}
template <class T>
inline
ThreadLocalStorage<T>::ThreadLocalStorage(const ThreadLocalStorage<T> &threadLocalStorage)
{ // copy constructor is private
}
template <class T>
inline
ThreadLocalStorage<T> &ThreadLocalStorage<T>::operator=(const ThreadLocalStorage<T> &threadLocalaStorage)
{ // assignment operator is private
return *this;
}
template <class T>
inline
bool ThreadLocalStorage<T>::getThreadData(SmartPointer<T> &threadData)
{
ThreadStorage<T> threadStorage;
SmartPointer<ThreadStorage<T> > pThreadStorage;
threadStorage.setThreadId(::GetCurrentThreadId());
if(!searchItem(threadStorage,pThreadStorage))return false;
threadData=&pThreadStorage->getData();
return true;
}
template <class T>
inline
bool ThreadLocalStorage<T>::haveThreadData(void)
{
ThreadStorage<T> threadStorage;
threadStorage.setThreadId(::GetCurrentThreadId());
return searchItem(threadStorage);
}
template <class T>
inline
void ThreadLocalStorage<T>::removeThreadData(void)
{
if(!haveThreadData())return;
ThreadStorage<T> threadStorage;
threadStorage.setThreadId(::GetCurrentThreadId());
remove(threadStorage);
}
template <class T>
inline
bool ThreadLocalStorage<T>::addThreadData(const T &data)
{
if(haveThreadData())return false;
ThreadStorage<T> threadStorage;
threadStorage.setThreadId(::GetCurrentThreadId());
threadStorage.setData(data);
return insert(threadStorage);
}
#endif

182
thread/thread.001 Normal file
View File

@@ -0,0 +1,182 @@
# Microsoft Developer Studio Project File - Name="thread" - Package Owner=<4>
# Microsoft Developer Studio Generated Build File, Format Version 5.00
# ** DO NOT EDIT **
# TARGTYPE "Win32 (x86) Static Library" 0x0104
CFG=thread - Win32 Release
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
!MESSAGE use the Export Makefile command and run
!MESSAGE
!MESSAGE NMAKE /f "thread.mak".
!MESSAGE
!MESSAGE You can specify a configuration when running NMAKE
!MESSAGE by defining the macro CFG on the command line. For example:
!MESSAGE
!MESSAGE NMAKE /f "thread.mak" CFG="thread - Win32 Release"
!MESSAGE
!MESSAGE Possible choices for configuration are:
!MESSAGE
!MESSAGE "thread - Win32 Release" (based on "Win32 (x86) Static Library")
!MESSAGE "thread - Win32 Debug" (based on "Win32 (x86) Static Library")
!MESSAGE
# Begin Project
# PROP Scc_ProjName ""
# PROP Scc_LocalPath ""
CPP=cl.exe
!IF "$(CFG)" == "thread - Win32 Release"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 0
# PROP BASE Output_Dir ".\Release"
# PROP BASE Intermediate_Dir ".\Release"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 0
# PROP Output_Dir ".\Release"
# PROP Intermediate_Dir ".\Release"
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /c
# ADD CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LIB32=link.exe -lib
# ADD BASE LIB32 /nologo
# ADD LIB32 /nologo
!ELSEIF "$(CFG)" == "thread - Win32 Debug"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 1
# PROP BASE Output_Dir ".\Debug"
# PROP BASE Intermediate_Dir ".\Debug"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 1
# PROP Output_Dir ".\msvcobj"
# PROP Intermediate_Dir ".\msvcobj"
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /GX /Z7 /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /c
# ADD CPP /nologo /Zp1 /MTd /Z7 /O2 /I "\work" /I "\parts" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "__FLAT__" /D "STRICT" /Fp"..\exe\msvc42.pch" /YX"windows.h" /FD /c
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LIB32=link.exe -lib
# ADD BASE LIB32 /nologo
# ADD LIB32 /nologo /out:"..\exe\msthread.lib"
!ENDIF
# Begin Target
# Name "thread - Win32 Release"
# Name "thread - Win32 Debug"
# Begin Group "Source Files"
# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;hpj;bat;for;f90"
# Begin Source File
SOURCE=.\Event.cpp
# End Source File
# Begin Source File
SOURCE=.\Msgqueue.cpp
# End Source File
# Begin Source File
SOURCE=.\Mthread.cpp
# End Source File
# Begin Source File
SOURCE=.\Mutex.cpp
# End Source File
# Begin Source File
SOURCE=.\Ptcllbck.cpp
# End Source File
# Begin Source File
SOURCE=.\Qthread.cpp
# End Source File
# Begin Source File
SOURCE=.\Stdtmpl.cpp
# End Source File
# Begin Source File
SOURCE=.\Thread.cpp
# End Source File
# Begin Source File
SOURCE=.\thtimer.cpp
# End Source File
# End Group
# Begin Group "Header Files"
# PROP Default_Filter "h;hpp;hxx;hm;inl;fi;fd"
# Begin Source File
SOURCE=.\Context.hpp
# End Source File
# Begin Source File
SOURCE=.\Event.hpp
# End Source File
# Begin Source File
SOURCE=.\Msgqueue.hpp
# End Source File
# Begin Source File
SOURCE=.\Mthread.hpp
# End Source File
# Begin Source File
SOURCE=.\Mutex.hpp
# End Source File
# Begin Source File
SOURCE=.\Postfix.hpp
# End Source File
# Begin Source File
SOURCE=.\Ptcllbck.hpp
# End Source File
# Begin Source File
SOURCE=.\Qthread.hpp
# End Source File
# Begin Source File
SOURCE=.\Savearea.hpp
# End Source File
# Begin Source File
SOURCE=.\Tcallbck.hpp
# End Source File
# Begin Source File
SOURCE=.\Thmsg.hpp
# End Source File
# Begin Source File
SOURCE=.\Thread.hpp
# End Source File
# Begin Source File
SOURCE=.\thtimer.hpp
# End Source File
# End Group
# Begin Group "Resource Files"
# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;cnt;rtf;gif;jpg;jpeg;jpe"
# End Group
# Begin Source File
SOURCE=.\Tcallbck.tpp
# End Source File
# End Target
# End Project

188
thread/thread.dsp Normal file
View File

@@ -0,0 +1,188 @@
# Microsoft Developer Studio Project File - Name="thread" - Package Owner=<4>
# Microsoft Developer Studio Generated Build File, Format Version 6.00
# ** DO NOT EDIT **
# TARGTYPE "Win32 (x86) Static Library" 0x0104
CFG=thread - Win32 Release
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
!MESSAGE use the Export Makefile command and run
!MESSAGE
!MESSAGE NMAKE /f "thread.mak".
!MESSAGE
!MESSAGE You can specify a configuration when running NMAKE
!MESSAGE by defining the macro CFG on the command line. For example:
!MESSAGE
!MESSAGE NMAKE /f "thread.mak" CFG="thread - Win32 Release"
!MESSAGE
!MESSAGE Possible choices for configuration are:
!MESSAGE
!MESSAGE "thread - Win32 Release" (based on "Win32 (x86) Static Library")
!MESSAGE "thread - Win32 Debug" (based on "Win32 (x86) Static Library")
!MESSAGE
# Begin Project
# PROP AllowPerConfigDependencies 0
# PROP Scc_ProjName ""
# PROP Scc_LocalPath ""
CPP=cl.exe
RSC=rc.exe
!IF "$(CFG)" == "thread - Win32 Release"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 0
# PROP BASE Output_Dir ".\Release"
# PROP BASE Intermediate_Dir ".\Release"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 0
# PROP Output_Dir ".\Release"
# PROP Intermediate_Dir ".\Release"
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /c
# ADD CPP /nologo /Gz /MT /GX /O2 /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "__FLAT__" /D "STRICT" /YX /FD /c
# ADD BASE RSC /l 0x409
# ADD RSC /l 0x409
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LIB32=link.exe -lib
# ADD BASE LIB32 /nologo
# ADD LIB32 /nologo
!ELSEIF "$(CFG)" == "thread - Win32 Debug"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 1
# PROP BASE Output_Dir ".\Debug"
# PROP BASE Intermediate_Dir ".\Debug"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 1
# PROP Output_Dir ".\msvcobj"
# PROP Intermediate_Dir ".\msvcobj"
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /GX /Z7 /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /c
# ADD CPP /nologo /Gz /MTd /Zi /Od /I "\work" /I "\parts" /D "_DEBUG" /D "__FLAT__" /D "STRICT" /D "WIN32" /D "_WINDOWS" /Fp"..\exe\msvc42.pch" /YX"windows.h" /FD /c
# ADD BASE RSC /l 0x409
# ADD RSC /l 0x409
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LIB32=link.exe -lib
# ADD BASE LIB32 /nologo
# ADD LIB32 /nologo /out:"..\exe\msthread.lib"
!ENDIF
# Begin Target
# Name "thread - Win32 Release"
# Name "thread - Win32 Debug"
# Begin Group "Source Files"
# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;hpj;bat;for;f90"
# Begin Source File
SOURCE=.\Event.cpp
# End Source File
# Begin Source File
SOURCE=.\Msgqueue.cpp
# End Source File
# Begin Source File
SOURCE=.\Mthread.cpp
# End Source File
# Begin Source File
SOURCE=.\Mutex.cpp
# End Source File
# Begin Source File
SOURCE=.\Ptcllbck.cpp
# End Source File
# Begin Source File
SOURCE=.\Qthread.cpp
# End Source File
# Begin Source File
SOURCE=.\Stdtmpl.cpp
# End Source File
# Begin Source File
SOURCE=.\Thread.cpp
# End Source File
# Begin Source File
SOURCE=.\thtimer.cpp
# End Source File
# End Group
# Begin Group "Header Files"
# PROP Default_Filter "h;hpp;hxx;hm;inl;fi;fd"
# Begin Source File
SOURCE=.\Context.hpp
# End Source File
# Begin Source File
SOURCE=.\Event.hpp
# End Source File
# Begin Source File
SOURCE=.\Msgqueue.hpp
# End Source File
# Begin Source File
SOURCE=.\Mthread.hpp
# End Source File
# Begin Source File
SOURCE=.\Mutex.hpp
# End Source File
# Begin Source File
SOURCE=.\Postfix.hpp
# End Source File
# Begin Source File
SOURCE=.\Ptcllbck.hpp
# End Source File
# Begin Source File
SOURCE=.\Qthread.hpp
# End Source File
# Begin Source File
SOURCE=.\Savearea.hpp
# End Source File
# Begin Source File
SOURCE=.\Tcallbck.hpp
# End Source File
# Begin Source File
SOURCE=.\Thmsg.hpp
# End Source File
# Begin Source File
SOURCE=.\Thread.hpp
# End Source File
# Begin Source File
SOURCE=.\thtimer.hpp
# End Source File
# End Group
# Begin Group "Resource Files"
# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;cnt;rtf;gif;jpg;jpeg;jpe"
# End Group
# Begin Source File
SOURCE=.\Tcallbck.tpp
# End Source File
# End Target
# End Project

29
thread/thread.dsw Normal file
View File

@@ -0,0 +1,29 @@
Microsoft Developer Studio Workspace File, Format Version 6.00
# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
###############################################################################
Project: "thread"=.\thread.dsp - Package Owner=<4>
Package=<5>
{{{
}}}
Package=<4>
{{{
}}}
###############################################################################
Global:
Package=<5>
{{{
}}}
Package=<3>
{{{
}}}
###############################################################################

BIN
thread/thread.mdp Normal file

Binary file not shown.