/****************************************************************************** * * Title : threadUtility.c * Version 0.0 * * Description: thread utility routines. * Related files: * * Author: Lukas Tomasek, tomasekl@fzu.cz * ******************************************************************************/ /****************************************************************************** * Header files * ******************************************************************************/ #include #include #include "threadUtility.h" #include "errorHandler.h" #include /****************************************************************************** * Definitions * ******************************************************************************/ #define TIME_LIMIT 4.0 /* time limit for a thread to return in seconds */ /****************************************************************************** * Global functions * ******************************************************************************/ /*============================================================================= * closeThread() *============================================================================= * * */ ERROR_ID closeThread(HANDLE threadHandle){ unsigned long int exitCode; double startTime; /* time in seconds */ int status; char errorMessage[200]; ERROR_ID errorId=SUCCESS; errorId=setThreadPriority(threadHandle,THREAD_PRIORITY_ABOVE_NORMAL); ERROR_CHECK(errorId,setThreadPriority()); startTime=Timer(); do{ status=GetExitCodeThread(threadHandle, &exitCode); if(status!=TRUE){ programError(__FILE__,__LINE__, PROGRAM_ERROR, "GetExitCodeThread()", GetLastError(), ""); } if((exitCode==0)||((Timer()-startTime)>TIME_LIMIT)) { break; } Sleep(50); } while(1); /* if thread still running - terminate it */ if((exitCode!=0)||(exitCode==STILL_ACTIVE)) { status=TerminateThread(threadHandle, 0); if(status!=TRUE){ sprintf(errorMessage,"Thread #%d terminated, exit=%d", threadHandle,exitCode); programError(__FILE__,__LINE__, PROGRAM_ERROR, "TerminateThread()", GetLastError(), errorMessage); MessagePopup ("WARNING", errorMessage); } } status=CloseHandle(threadHandle); if(status!=TRUE){ programError(__FILE__,__LINE__, PROGRAM_ERROR, "CloseHandle()", GetLastError(), "CloseHandle(threadHandle)"); MessagePopup ("WARNING", "CloseHandle(threadHandle)"); } return (errorId); } /*============================================================================= * createThread() *============================================================================= * * * */ ERROR_ID createThread(struct THREAD_INFO *thread, LPTHREAD_START_ROUTINE functionName, void *functionArgument, int threadPriority){ int status; char errorMessage[200]; ERROR_ID errorId=SUCCESS; thread->handle=CreateThread( NULL, /* no security attributes */ 0, /* default stack size */ (LPTHREAD_START_ROUTINE) functionName, /* thread function */ functionArgument, /* no argument to thread function */ 0, /* default creation flags - thread immediately runs */ &thread->id); /* returns thread ID */ if(thread->handle == NULL){ errorId=FATAL_ERROR; programError(__FILE__,__LINE__, errorId, "CreateThread()", GetLastError(), ""); return(errorId); } thread->priority=threadPriority; status=SetThreadPriority(thread->handle,threadPriority); if(status!=TRUE){ errorId=FATAL_ERROR; programError(__FILE__,__LINE__, errorId, "SetThreadPriority()", GetLastError(), ""); } return(errorId); } /*============================================================================= * setPriorityClass() *============================================================================= * * * */ ERROR_ID setPriorityClass(int priorityClass){ int status; ERROR_ID errorId=SUCCESS; status=SetPriorityClass(GetCurrentProcess(), priorityClass); if(status!=TRUE){ errorId=FATAL_ERROR; programError(__FILE__,__LINE__, errorId, "SetPriorityClass()", GetLastError(), ""); } return(errorId); } /*============================================================================= * setThreadPriority() *============================================================================= * * * */ ERROR_ID setThreadPriority(HANDLE threadHandle, int threadPriority){ int status; ERROR_ID errorId=SUCCESS; status=SetThreadPriority(threadHandle, threadPriority); if(status!=TRUE){ errorId=FATAL_ERROR; programError(__FILE__,__LINE__, errorId, "SetThreadPriority()", GetLastError(), ""); } return(errorId); } /*============================================================================= * getThreadPriority() *============================================================================= * * * */ ERROR_ID getThreadPriority(HANDLE threadHandle, int *threadPriority){ int status; ERROR_ID errorId=SUCCESS; *threadPriority=GetThreadPriority(threadHandle); if(*threadPriority==THREAD_PRIORITY_ERROR_RETURN){ errorId=PROGRAM_ERROR; programError(__FILE__,__LINE__, errorId, "GetThreadPriority()", GetLastError(), ""); } return(errorId); } /*============================================================================= * createEvent() *============================================================================= * * * */ ERROR_ID createEvent(HANDLE *eventHandle, BOOL manualReset){ ERROR_ID errorId=SUCCESS; *eventHandle=CreateEvent(NULL, manualReset, FALSE, NULL); if (*eventHandle==NULL){ errorId=FATAL_ERROR; programError(__FILE__,__LINE__, errorId, "CreateEvent()", GetLastError(),""); } return(errorId); } /*============================================================================= * setEvent() *============================================================================= * * * */ ERROR_ID setEvent(HANDLE eventHandle){ int status; ERROR_ID errorId=SUCCESS; status=SetEvent(eventHandle); if (status!=TRUE){ errorId=FATAL_ERROR; programError(__FILE__,__LINE__, errorId, "SetEvent()", GetLastError(),""); } return(errorId); } /*============================================================================= * resetEvent() *============================================================================= * * * */ ERROR_ID resetEvent(HANDLE eventHandle){ int status; ERROR_ID errorId=SUCCESS; status=ResetEvent(eventHandle); if (status!=TRUE){ errorId=FATAL_ERROR; programError(__FILE__,__LINE__, errorId, "ResetEvent()", GetLastError(),""); } return(errorId); } /*============================================================================= * closeHandle() *============================================================================= * * * */ ERROR_ID closeHandle(HANDLE handle){ int status; ERROR_ID errorId=SUCCESS; status=CloseHandle(handle); if (status!=TRUE){ errorId=FATAL_ERROR; programError(__FILE__,__LINE__, errorId, "CloseHandle()", GetLastError(),""); } return(errorId); } /*============================================================================= * waitForEvent() *============================================================================= * * * */ ERROR_ID waitForEvent(HANDLE eventHandle){ int status; ERROR_ID errorId=SUCCESS; status=WaitForSingleObject(eventHandle, INFINITE); if ((status!=WAIT_OBJECT_0)||(status==WAIT_FAILED)){ errorId=FATAL_ERROR; programError(__FILE__,__LINE__, errorId, "WaitForSingleObject()", GetLastError(),""); } /* reset event for sure (not necessary) */ status=ResetEvent(eventHandle); if (status!=TRUE){ errorId=PROGRAM_ERROR; programError(__FILE__,__LINE__, errorId, "ResetEvent()", GetLastError(),""); } return(errorId); } /*============================================================================= * suspendThread() *============================================================================= * * * */ ERROR_ID suspendThread(HANDLE threadHandle){ int status; ERROR_ID errorId=SUCCESS; status=SuspendThread(threadHandle); if (status==-1){ errorId=FATAL_ERROR; programError(__FILE__,__LINE__, errorId, "SuspendThread()", GetLastError(),""); } return(errorId); } /*============================================================================= * resumeThread() *============================================================================= * * * */ ERROR_ID resumeThread(HANDLE threadHandle){ int status; ERROR_ID errorId=SUCCESS; status=ResumeThread(threadHandle); if (status==-1){ errorId=FATAL_ERROR; programError(__FILE__,__LINE__, errorId, "ResumeThread()", GetLastError(),""); } return(errorId); } /*============================================================================= * interlockedIncrement() *============================================================================= * * * */ ERROR_ID interlockedIncrement(long *variable){ long longStatus; ERROR_ID errorId=SUCCESS; longStatus=InterlockedIncrement(variable); if(longStatus<=0){ errorId=FATAL_ERROR; //error } return(errorId); } /*============================================================================= * interlockedDecrement() *============================================================================= * * * */ ERROR_ID interlockedDecrement(long *variable){ long longStatus; ERROR_ID errorId=SUCCESS; if(*variable<=0){ errorId=FATAL_ERROR; return(errorId); } longStatus=InterlockedDecrement(variable); if(longStatus<0){ errorId=FATAL_ERROR; //error } return(errorId); } /******************************************************************************/