Go to the documentation of this file.00001 #include "FunctionThread.h"
00002 #include "RakSleep.h"
00003
00004 using namespace RakNet;
00005
00006 #ifdef _MSC_VER
00007 #pragma warning( push )
00008 #endif
00009
00010 FunctionThread::FunctorAndContext WorkerThreadFunc(FunctionThread::FunctorAndContext input, bool *returnOutput, void* perThreadData)
00011 {
00012 (void) perThreadData;
00013
00014 FunctionThread::FunctorAndContext output;
00015 input.functor->Process(input.context);
00016 output.functor=input.functor;
00017 output.context=input.context;
00018 *returnOutput=true;
00019 return output;
00020 }
00021 FunctionThread::FunctionThread()
00022 {
00023 pr=0;
00024 }
00025 FunctionThread::~FunctionThread()
00026 {
00027 StopThreads(false);
00028 }
00029 void FunctionThread::StartThreads(int numThreads)
00030 {
00031 threadPool.StartThreads(numThreads, 0, 0, 0);
00032 }
00033 void FunctionThread::StopThreads(bool blockOnCurrentProcessing)
00034 {
00035
00036 CancelInput();
00037 while (blockOnCurrentProcessing && threadPool.IsWorking())
00038 {
00039 CallResultHandlers();
00040 RakSleep(30);
00041 }
00042 threadPool.StopThreads();
00043 }
00044 void FunctionThread::Push(Functor *functor, void *context)
00045 {
00046 FunctorAndContext input;
00047 input.functor=functor;
00048 input.context=context;
00049 threadPool.AddInput(WorkerThreadFunc, input);
00050 }
00051 void FunctionThread::CallResultHandlers(void)
00052 {
00053 FunctorAndContext functorAndResult;
00054 while (threadPool.HasOutputFast() && threadPool.HasOutput())
00055 {
00056 functorAndResult = threadPool.GetOutput();
00057 functorAndResult.functor->HandleResult(false, functorAndResult.context);
00058 if (pr) pr(functorAndResult);
00059 }
00060 }
00061 void FunctionThread::CancelFunctorsWithContext(bool (*cancelThisFunctor)(FunctionThread::FunctorAndContext func, void *userData), void *userData)
00062 {
00063 FunctorAndContext functorAndResult;
00064 unsigned i;
00065 threadPool.LockInput();
00066 for (i=0; i < threadPool.InputSize(); i++)
00067 {
00068 functorAndResult = threadPool.GetInputAtIndex(i);
00069 if (cancelThisFunctor(functorAndResult, userData))
00070 {
00071 functorAndResult.functor->HandleResult(true, functorAndResult.context);
00072 if (pr) pr(functorAndResult);
00073 }
00074 }
00075 threadPool.ClearInput();
00076 threadPool.UnlockInput();
00077 }
00078 void FunctionThread::SetPostResultFunction(void (*postResult)(FunctionThread::FunctorAndContext func))
00079 {
00080 pr=postResult;
00081 }
00082 void FunctionThread::CancelInput(void)
00083 {
00084
00085 FunctorAndContext functorAndResult;
00086 unsigned i;
00087 threadPool.LockInput();
00088 for (i=0; i < threadPool.InputSize(); i++)
00089 {
00090 functorAndResult = threadPool.GetInputAtIndex(i);
00091 functorAndResult.functor->HandleResult(true, functorAndResult.context);
00092 if (pr) pr(functorAndResult);
00093 }
00094 threadPool.ClearInput();
00095 threadPool.UnlockInput();
00096 }
00097
00098 FunctionThreadDependentClass::FunctionThreadDependentClass()
00099 {
00100 functionThreadWasAllocated=false;
00101 functionThread=0;
00102 }
00103 FunctionThreadDependentClass::~FunctionThreadDependentClass()
00104 {
00105 if (functionThreadWasAllocated)
00106 RakNet::OP_DELETE(functionThread, __FILE__, __LINE__);
00107 }
00108
00109 void FunctionThreadDependentClass::AssignFunctionThread(FunctionThread *ft)
00110 {
00111 if (functionThread && functionThreadWasAllocated)
00112 {
00113 functionThread->StopThreads(true);
00114 RakNet::OP_DELETE(functionThread, __FILE__, __LINE__);
00115 }
00116
00117 functionThread=ft;
00118 functionThreadWasAllocated=false;
00119 }
00120
00121 void FunctionThreadDependentClass::StartFunctionThread(void)
00122 {
00123 if (functionThread==0)
00124 {
00125 functionThread = RakNet::OP_NEW<FunctionThread>( __FILE__, __LINE__ );
00126 functionThreadWasAllocated=true;
00127 }
00128
00129 functionThread->StartThreads(1);
00130 }
00131 FunctionThread *FunctionThreadDependentClass::GetFunctionThread(void) const
00132 {
00133 return functionThread;
00134 }
00135 bool FunctionThreadDependentClass::GetFunctionThreadWasAllocated(void) const
00136 {
00137 return functionThreadWasAllocated;
00138 }
00139 void FunctionThreadDependentClass::PushFunctor(Functor *functor, void *context)
00140 {
00141 StartFunctionThread();
00142 functionThread->Push(functor, context);
00143 }
00144
00145 #ifdef _MSC_VER
00146 #pragma warning( pop )
00147 #endif