/** * Copyright - See the COPYRIGHT that is included with this distribution. * EPICS pvData is distributed subject to a Software License Agreement found * in file LICENSE that is included with this distribution. */ /* * testThread.cpp * * Created on: 2010.11 * Author: Marty Kraimer */ #include #include #include #include #include #include #include #include #include #include #include #include using namespace epics::pvData; static String actionName("action"); class Action; typedef std::tr1::shared_ptr ActionPtr; class Action : public Runnable { public: virtual ~Action() {} FILE *out; bool actuallyRan; Event begin, end; Action(FILE* fp): out(fp), actuallyRan(false) {} virtual void run() { fprintf(out, "Action waiting\n"); begin.signal(); bool waited=end.wait(); actuallyRan=true; fprintf(out, "Action %s\n", waited?"true":"false"); } }; typedef std::tr1::shared_ptr ThreadPtr; static void testThreadRun(FILE *fd) { // show that we can control thread start and stop ActionPtr ax(new Action(fd)); { ThreadPtr tr(new Thread(actionName,lowPriority,ax.get())); bool w=ax->begin.wait(); fprintf(fd, "main %s\n", w?"true":"false"); fprintf(fd, "Action is %s\n", ax->actuallyRan?"true":"false"); ax->end.signal(); } fprintf(fd, "Action is %s\n", ax->actuallyRan?"true":"false"); fprintf(fd,"testThreadRun PASSED\n"); } class Basic; typedef std::tr1::shared_ptr BasicPtr; class Basic : public Command, public std::tr1::enable_shared_from_this { public: POINTER_DEFINITIONS(Basic); Basic(ExecutorPtr const &executor) : executor(executor) {} ~Basic() { } void run() { executor->execute(getPtrSelf()); bool result = wait.wait(); if(result==false) printf("basic::run wait returned false\n"); } virtual void command() { wait.signal(); } private: Basic::shared_pointer getPtrSelf() { return shared_from_this(); } ExecutorPtr executor; Event wait; }; typedef std::tr1::shared_ptr BasicPtr; static void testBasic(FILE *fd) { ExecutorPtr executor(new Executor(String("basic"),middlePriority)); BasicPtr basic( new Basic(executor)); basic->run(); fprintf(fd,"testBasic PASSED\n"); } class MyFunc : public TimeFunctionRequester { public: POINTER_DEFINITIONS(MyFunc); MyFunc(BasicPtr const &basic); virtual void function(); private: BasicPtr basic; }; MyFunc::MyFunc(BasicPtr const &basic) : basic(basic) {} void MyFunc::function() { basic->run(); } typedef std::tr1::shared_ptr MyFuncPtr; #ifdef TESTTHREADCONTEXT static void testThreadContext(FILE *fd,FILE *auxFd) { ExecutorPtr executor(new Executor(String("basic"),middlePriority)); BasicPtr basic(new Basic(executor)); MyFuncPtr myFunc(new MyFunc(basic)); TimeFunctionPtr timeFunction(new TimeFunction(myFunc)); double perCall = timeFunction->timeCall(); perCall *= 1e6; fprintf(auxFd,"time per call %f microseconds\n",perCall); fprintf(fd,"testThreadContext PASSED\n"); } #endif int main(int argc, char *argv[]) { char *fileName = 0; if(argc>1) fileName = argv[1]; FILE * fd = stdout; if(fileName!=0 && fileName[0]!=0) { fd = fopen(fileName,"w+"); } char *auxFileName = 0; if(argc>2) auxFileName = argv[2]; FILE *auxFd = stdout; if(auxFileName!=0 && auxFileName[0]!=0) { auxFd = fopen(auxFileName,"w+"); } testThreadRun(fd); testBasic(fd); #ifdef TESTTHREADCONTEXT testThreadContext(fd,auxFd); #endif return 0; }