int TaskManager::loadWorker(std::string workerFileName, OSFileSys* fsys) { int result = 0; int errorCount = 0; std::auto_ptr<EParser> aTest(new EParser(m_ostr)); //EParser* aTest = new EParser(m_ostr); aTest->setFilename(workerFileName); int res = aTest->extractInclude(workerFileName, TaskConfig::getDeployHome()); if(res != 0){ result = res; errorCount = res; } if(aTest->getInclude() != 0){ //preprocessing include EList<std::string> includedFiles = aTest->getInclude()->getIncludeFiles(); if(includedFiles.moveHead()){ do{ std::string fName = includedFiles.getCurObject(); //parsing LOG_TRACE(m_log, "Reading the file, '%s'...", fName.c_str()); aTest->setFilename(fName); errorCount = aTest->parseScript(TaskConfig::getDeployHome() + fName); if(errorCount>0){ result = errorCount; ///////////////////////////////////에러코드정리 LOG_ERROR(m_log, "Parser can not open the file '%s'.", fName.c_str()); break; } } while(includedFiles.moveNext()); } } if(errorCount == 0){ GparsedResult* pRslt = aTest->getParsingResult(); EList<Genum*>* enumlist = pRslt->getEnums(); EList<Gmodel*>* modellist = pRslt->getModels(); EList<Gaction*>* actionlist = pRslt->getActions(); // EList<Gworker*>* workerlist = pRslt->getWorkers(); //예전 방법 task 정의 EList<Gtask*>* tasklist = pRslt->getTasks(); //최근 방법 task 정의 EList<Gbehavior*>* bhvlist = pRslt->getbehaviors(); EList<Gconnector*>* connlist = pRslt->getconnectors(); SymTAB4Task* newSymT = new SymTAB4Task(); std::auto_ptr<RTObjBuilder> rtmBuilder(new RTObjBuilder(m_ostr, newSymT)); //RTObjBuilder *rtmBuilder = new RTObjBuilder(m_ostr, newSymT); EList<RFSMtask*>* rtasks = NULL; EList<RFSMbehavior*>* rbhvs = NULL; EList<RFSMconnector*>* rconns = NULL; try{ //model, action, enum 검사 LOG_TRACE(m_log, "Checking Model composed of Symbol, Function, Action and Enum ..."); rtmBuilder->makeSymTable(pRslt); //TASK 명세 검사 LOG_TRACE(m_log, "Checking Tasks ..."); rtasks = rtmBuilder->checkSemantics(tasklist); rbhvs = rtmBuilder->checkSemantics(bhvlist); rconns = rtmBuilder->checkSemantics(connlist); //Model 파일수가 여러개 이더라도 1개의 심볼테이블이 만들어진다. //파일이 나누어져도 하나의 파일로 간주 //SymTAB4Task* newSymT = rtmBuilder->getSymT(); /* if(workerlist !=NULL && workerlist->getSize()>0 && workerlist->moveHead()){ do{ Gworker* worker = workerlist->getCurObject(); std::string workerName = worker->getName()->getData(); //Task 들을 등록 result = m_taskMem->addTask(workerName, worker->getStartBhv()->getData()); //심볼테이블 등록 if(result ==0){ newSymT->pluRefCount(); result = m_taskMem->addSymbolT(workerName, newSymT); } else result = 100; ///////////////////////////////////에러코드정리 } while(workerlist->moveNext()); } */ if(rtasks !=NULL && rtasks->getSize()>0 && rtasks->moveHead()){ do{ RFSMtask* task = rtasks->getCurObject(); std::string taskName = task->getName(); //Task 들을 등록 result = m_taskMem->addTask2(taskName, task); //여기까지 했다 다음부터 구현 할 것 //심볼테이블 등록 if(result ==0){ newSymT->pluRefCount(); result = m_taskMem->addSymbolT(taskName, newSymT); } else result = 100; ///////////////////////////////////에러코드정리 } while(rtasks->moveNext()); } // else // delete newSymT; //task가 없으면 나중에 지울 수가 없기 때문에... //Behavior 등록 if(result ==0){ if(rbhvs != NULL && rbhvs->getSize()>0 && rbhvs->moveHead()){ do{ RFSMbehavior* bhv = rbhvs->getCurObject(); //아래 순서 중요.. 모니터링에서 behavior테이블로 중복을 검사하기 때문에 //1. 모니터링 정보 등록 m_taskMem->addMonitorInfo(bhv); //2. behavior등록 result = m_taskMem->addBehavior(bhv); } while(rbhvs->moveNext()); } if(rconns != NULL && rconns->getSize()>0 && rconns->moveHead()){ do{ RFSMconnector* rconn= rconns->getCurObject(); //아래 순서 중요.. 모니터링에서 behavior테이블로 중복을 검사하기 때문에 //1. 모니터링 정보 등록 //m_taskMem->addMonitorInfo(rconn); //2. behavior등록 result = m_taskMem->addConnector(rconn); } while(rconns->moveNext()); } } else result = 100; ///////////////////////////////////에러코드정리 /* //bhv에 관련된 worker이름을 저장 if(result ==0){ if(workerlist !=NULL && workerlist->getSize()>0 && workerlist->moveHead()){ do{ Gworker* worker = workerlist->getCurObject(); std::string workerName = worker->getName()->getData(); std::string startBhvName = worker->getStartBhv()->getData(); RFSMbehavior* t = m_taskMem->findBehavior(startBhvName); if(t == NULL){//task의 시작 behavior가 존재하지 않는 경우 LOG_ERROR(m_log, "The root behavior, <%s()>, cannot be found.", startBhvName.c_str()); return 100;////////////////////////에러코드정리 } else{ t->addRefTask(workerName); EList<std::string> tlist; setWorkerName(t, workerName, tlist); //각각의 worker에 대해서 dot파일 생성 std::string dot = getDot(workerName, t, tlist); std::ofstream dotfile; std::string dotfilename = workerName; dotfilename.append(".dot"); dotfile.open(dotfilename.c_str()); dotfile << dot.c_str() << "\n"; dotfile.flush(); dotfile.close(); LOG_TRACE(m_log, "%s.dot file, which represents graphical view of a worker, is created.", workerName.c_str()); } } while(workerlist->moveNext()); } } */ //bhv에 관련된 worker이름을 저장 if(result ==0){ if(rtasks !=NULL && rtasks->getSize()>0 && rtasks->moveHead()){ do{ RFSMtask* task = rtasks->getCurObject(); std::string taskName = task->getName(); //task에 포함된 모든 behavior와 conexer의 이름 std::vector<RFSMstmt*>* runBlock = task->getRunBlock(); std::vector<std::string> startList; task->extractStartNodes(runBlock, startList); //runblock에 포함된 모든 behavior나 conexer에 대해서 std::vector<std::string>::iterator it; for(it=startList.begin(); it<startList.end(); it++){ std::string startNodeName = *it; RFSMtreenode* startNode = m_taskMem->findBehavior(startNodeName); if(startNode == NULL){//task의 시작 behavior가 존재하지 않는 경우 startNode = m_taskMem->findConnector(startNodeName); if(startNode == NULL){ LOG_ERROR(m_log, "The root node(behavior or conexer), <%s()>, cannot be found.", startNodeName.c_str()); result = 100;////////////////////////에러코드정리 break; } } startNode->addRefTask(taskName); EList<std::string> tlist; // for dot setWorkerName(startNode, taskName, tlist); tlist.clearAllchild(); //이걸해야 tlist의 new EListElement<T>(obj); 으로 만들어진 부분이 삭제된다. } //각각의 worker에 대해서 dot파일 생성 // 아래 부분은 task노드를 root로 하는 구조로 바뀌어야 한다. /* std::string dot = getDot(taskName, t, tlist); std::ofstream dotfile; std::string dotfilename = taskName; dotfilename.append(".dot"); dotfile.open(dotfilename.c_str()); dotfile << dot.c_str() << "\n"; dotfile.flush(); dotfile.close(); LOG_TRACE(m_log, "%s.dot file, which represents graphical view of a worker, is created.", taskName.c_str()); */ } while(result == 0 && rtasks->moveNext()); } } if(rtasks != 0 && rtasks->getSize()>0 && rtasks->moveHead()){ do{ RFSMtreenode* rtask = rtasks->getCurObject(); setSubNodes(rtask); }while(rtasks->moveNext()); } if(rbhvs != 0 && rbhvs->getSize()>0 && rbhvs->moveHead()){ do{ RFSMtreenode* rbhv = rbhvs->getCurObject(); setSubNodes(rbhv); }while(rbhvs->moveNext()); } if(rconns != 0 && rconns->getSize()>0 && rconns->moveHead()){ do{ RFSMtreenode* rconn = rconns->getCurObject(); setSubNodes(rconn); }while(rconns->moveNext()); } if(rconns != 0 && rconns->getSize()>0 && rconns->moveHead()){ do{ RFSMconnector* rconn = (RFSMconnector*)rconns->getCurObject(); std::map<int, int> synchInfo = checkValidSynchIDs(rconn); rconn->setSynchInfo(synchInfo); //rconn->checkValidSynchIDs(); }while(rconns->moveNext()); } if(rtasks != 0 && rtasks->getSize()>0 && rtasks->moveHead()){ do{ std::set<int> ids; RFSMtask* rtask = (RFSMtask*)(rtasks->getCurObject()); rtask->setSynchidInTask(); }while(rtasks->moveNext()); } /* 삭제(껍데기만 내용은 TaskMem에 저장) */ if(rtasks != NULL){ while(rtasks->getSize()>0 && rtasks->moveHead()){ //RFSMtask* obj = rtasks->getCurObject(); //delete obj; rtasks->delHead(); } delete rtasks; rtasks = NULL; } if(rbhvs != NULL){ while(rbhvs->getSize()>0 && rbhvs->moveHead()){ //RFSMbehavior* obj = rbhvs->getCurObject(); //delete obj; rbhvs->delHead(); } delete rbhvs; rbhvs = NULL; } if(rconns != NULL){ while(rconns->getSize()>0 && rconns->moveHead()){ //RFSMconnector* obj = rconns->getCurObject(); //delete obj; rconns->delHead(); } delete rconns; rconns = NULL; } /* //시나리오 파일 처리 if(pRslt->getSCs().size()>0){ std::string inclstr; if(aTest->getInclude() != 0){ Ginclude* inclList = aTest->getInclude(); if(inclList->moveHead()){ do{ Gtoken* tok = inclList->getCurObject(); std::string fname = tok->getFileName(); std::string incl = tok->getData(); if(fname==workerFileName) inclstr.append("#include \"").append(incl).append("\"\n"); } while(inclList->moveNext()); } } TPLGenerator tplGen(fsys, workerFileName, inclstr, pRslt->getSTasks(), pRslt->getSCs(), pRslt->getSBehaviors(), pRslt->getSEvents()); tplGen.generateTPL(); } */ } catch(SemanticsEH& semEH){ LOG_ERROR(m_log, "The parser returned %d errors, Task loading aborted.", semEH.hasError_()); delete newSymT; newSymT = NULL; delete rtasks; rtasks = NULL; delete rbhvs; rbhvs = NULL; delete rconns; rconns = NULL; result = 100;/////////////////////////////////////////////////////에러코드 정리 } } //aTest 에서 pRslt가 지워진다. //delete aTest; return result; }
int TaskManager::unloadWorker(std::string workerName) { //먼저 실행 중이 task는 모두 삭제부터 한다. stopAllWorker(); //worker목록 제거 /* StrMap* taskTAB = m_taskMem->getTaskTAB(); StrMap::iterator it1 = taskTAB->find(workerName); if(it1 != taskTAB->end()){ taskTAB->erase(it1); } else{ TaskTAB* taskTAB2 = m_taskMem->getTaskTAB2(); TaskTAB::iterator it2 = taskTAB2->find(workerName); if(it2 != taskTAB2->end()){ delete it2->second; taskTAB2->erase(it2); } else{ LOG_ERROR(m_log, "Task <%s> dose not exist in the loaded task list.", workerName.c_str()); return DB_UNLOAD_ERR_NO_WORKER; } } */ TaskTAB* taskTAB2 = m_taskMem->getTaskTAB2(); TaskTAB::iterator it2 = taskTAB2->find(workerName); if(it2 != taskTAB2->end()){ delete it2->second; taskTAB2->erase(it2); } else{ LOG_ERROR(m_log, "Task <%s> dose not exist in the loaded task list.", workerName.c_str()); return DB_UNLOAD_ERR_NO_WORKER; } //worker에서 이용하는 model(심볼테이블) 삭제 SymTAB* symTAB = m_taskMem->getSymbolTAB(); SymTAB::iterator it = m_taskMem->getSymbolTAB()->find(workerName); if(it != symTAB->end()){ SymTAB4Task* symT = it->second; if(symT->getWorkerRefCount() <= 1){ delete symT; } else{ symT->minRefCount(); } symTAB->erase(it); } else{ LOG_ERROR(m_log, "The symbol table for task <%s> dose not exist", workerName.c_str()); return DB_UNLOAD_ERR_NO_SYMTAB; } //worker에 포함된 bhv 찾기 EList<std::string> delList; BehaviorTAB* behaviorTAB = m_taskMem->getBehaviorTAB(); BehaviorTAB::iterator it3 = behaviorTAB->begin(); for(; it3!=behaviorTAB->end(); it3++){ RFSMbehavior* t = it3->second; int wNum = t->unRefTask(workerName); if(wNum == 0){//bhv를 이용하는 worker가 하나도 없으면 //unloadTask(it3->first); //map을 검색하면서 자신을 지우면 안된다. delList.addTail(it3->first); } } /* if(delList.moveHead()){ do{ std::string tName = delList.getCurObject(); unloadBehavior(tName); } while(delList.moveNext()); } */ while(delList.moveHead()){ std::string tName = delList.getCurObject(); unloadBehavior(tName); delList.delHead(); } //m_taskMem->leakTest(); //conexer삭제 EList<std::string> delConList; ConnectorTAB* conTAB = m_taskMem->getConnectorTAB(); ConnectorTAB::iterator it4 = conTAB->begin(); for(; it4!=conTAB->end(); it4++){ RFSMconnector* con = it4->second; int wNum = con->unRefTask(workerName); if(wNum == 0){//bhv를 이용하는 worker가 하나도 없으면 //unloadTask(it3->first); //map을 검색하면서 자신을 지우면 안된다. delConList.addTail(it4->first); } } while(delConList.getSize()>0 && delConList.moveHead()){ std::string cName = delConList.getCurObject(); unloadConnector(cName); delConList.delHead(); } //monitor리스트 삭제 return 0; }
std::string TaskManager::getDot(std::string workerName, RFSMtreenode* startNode, EList<std::string> tlist) { RFSMbehavior* startTask = (RFSMbehavior*)startNode; if(typeid(*startNode)==typeid(RFSMbehavior)){ } else if(typeid(*startNode)==typeid(RFSMconnector)){ return ""; } else{ return ""; } std::string dot; dot.append("digraph G{\n"); dot.append("compound=true;\n"); // 1.Pre declaration if(tlist.getSize()>0 && tlist.moveHead()){ do{ dot.append("subgraph cluster");//RFSMtask에서 이름앞에 'cluster'를 사용 dot.append(tlist.getCurObject()); dot.append(";\n"); } while(tlist.moveNext()); } // 2. worker의 시작 bhv dot.append(startTask->getDot()); // 3. worker의 시작 Task에서 분기되는 Task들 std::vector<std::string> linkedTasks = startTask->getLinkedNodes(); if(linkedTasks.size()>0){ for(unsigned int i =0; i<linkedTasks.size();i++){ std::string tName = linkedTasks[i]; RFSMbehavior* t = m_taskMem->findBehavior(tName); if(t != NULL){ std::string taskDot = t->getDot(); dot.append(taskDot); } } } // 4. %taskname%을 initial state 명으로 바꾼다. while(true){ int s = dot.find_first_of("%"); int e = dot.find_first_of("*"); if(s<0 || e<0)break; std::string sub = dot.substr(s, e-s+1);//시작, 시작으로부터offset std::string stName = dot.substr(s+1, e-s-1); RFSMbehavior* tt = m_taskMem->findBehavior(stName); if(tt != NULL && tt->getInitialState() != NULL){ std::string isName = tt->getInitialState()->getName(); Estring::replaceAll(dot, sub, RFSMnamedItem::removePath(isName)); } else{ //무한루프를 빠져나오기 위해서 bhv가 없더라도 반드시 %,*가 없는 이름으로 변환 Estring::replaceAll(dot, sub, stName); } } dot.append("}\n"); return dot; }