static Symbol* fkt_begin_critical(const std::vector<Symbol*>& vecSyms, ParseInfo& info, RuntimeInfo &runinfo, SymbolTable* pSymTab) { // no argument given: lock global mutex if(vecSyms.size() == 0) { info.pmutexGlobal->lock(); } else { for(Symbol* pSym : vecSyms) { if(pSym->GetType() == SYMBOL_ARRAY) fkt_begin_critical(((SymbolArray*)pSym)->GetArr(), info, runinfo, pSymTab); else if(pSym->GetType() == SYMBOL_INT) { //std::lock_guard<std::mutex> lck(*info.pmutexCrit); int iHandle = pSym->GetValInt(); Handle *pHandle = info.phandles->GetHandle(iHandle); if(pHandle==0 || pHandle->GetType()!=HANDLE_MUTEX) { std::ostringstream ostrErr; ostrErr << linenr(runinfo) << "Handle (" << iHandle << ") does not exist" << " or is not a mutex handle. Ignoring." << std::endl; throw tl::Err(ostrErr.str(), 0); //continue; } std::mutex *pMutex = ((HandleMutex*)pHandle)->GetInternalHandle(); pMutex->lock(); } else { std::ostringstream ostrErr; ostrErr << linenr(runinfo) << "Invalid mutex handle: " << pSym->print() << " Ignoring." << std::endl; throw tl::Err(ostrErr.str(), 0); } } } return 0; }
static Symbol* fkt_thread_join(const std::vector<Symbol*>& vecSyms, ParseInfo& info, RuntimeInfo &runinfo, SymbolTable* pSymTab) { if(vecSyms.size()<1) { std::ostringstream ostrErr; ostrErr << linenr(runinfo) << "join needs at least one argument." << std::endl; throw tl::Err(ostrErr.str(),0); } Symbol *pRet = 0; for(Symbol* pSym : vecSyms) { if(pSym == 0) continue; if(pSym->GetType() == SYMBOL_ARRAY) { return fkt_thread_join(((SymbolArray*)pSym)->GetArr(), info, runinfo, pSymTab); } if(pSym->GetType() != SYMBOL_INT) { std::ostringstream ostrErr; ostrErr << linenr(runinfo) << "join needs thread handles." << std::endl; throw tl::Err(ostrErr.str(), 0); //continue; } t_int iHandle = ((SymbolInt*)pSym)->GetVal(); Handle *pHandle = info.phandles->GetHandle(iHandle); if(pHandle==0) { std::ostringstream ostrErr; ostrErr << linenr(runinfo) << "Handle (" << iHandle << ") does not exist." << std::endl; throw tl::Err(ostrErr.str(), 0); //continue; } if(pHandle->GetType() == HANDLE_THREAD) { HandleThread *pThreadHandle = (HandleThread*)pHandle; std::thread *pThread = pThreadHandle->GetInternalHandle(); //log_debug("Joining thread ", pThread, "..."); pThread->join(); //log_debug("Joined thread ", pThread, "."); } else if(pHandle->GetType() == HANDLE_TASK) { HandleTask *pTaskHandle = (HandleTask*)pHandle; std::future<Symbol*> *pFut = pTaskHandle->GetInternalHandle(); // TODO: array task joins if(pRet != 0) delete pRet; pRet = pFut->get(); } else { std::ostringstream ostrErr; ostrErr << linenr(runinfo) << "Handle (" << iHandle << ") is invalid." << std::endl; throw tl::Err(ostrErr.str(), 0); } info.phandles->CloseHandle(iHandle); } return pRet; }