#include "PluginThread.h" /** * PluginThread */ #include "MonitorLogging.h" #ifdef WIN32 #define usleep Sleep #endif #define MAX_QUEUESIZE (100) PluginThread::PluginThread() : ThreadBase(-1) { FILE_LOG(logDEBUG) << "Erstellt PT:" ; m_iLockNum=-1 ; m_plugin=NULL ; m_bStop=false ; dll=NULL ; } bool PluginThread::initPlugin(int LOCKNUM, std::string dllfile,XMLNode *pConfig) { m_iLockNum=LOCKNUM ; char dllname[255] ; memset(dllname,0,255) ; strncpy(dllname,dllfile.c_str(),255) ; FILE_LOG(logDEBUG) << "DLL Name:" << dllname ; dll= new DLLFactory<MonitorPlugInFactory>(dllname); FILE_LOG(logDEBUG) << "done" ; // // If it worked we should have dll.factory pointing // to a subclass of PlugInFactory // if (dll) { if( dll->factory ) { m_plugin=dll->factory->CreatePlugIn() ; if (m_plugin==NULL) { ThrowMonitorException("Error creating Plugin !") ; } else { // Plugin ist erstellt, nun konfigurieren m_plugin->initProcessing(NULL,*pConfig) ; } } else { ThrowMonitorException("Error accessing factory from " + dllfile) ; } } else { ThrowMonitorException("Error loading dll:" + dllfile) ; } return true ; } PluginThread::PluginThread(int LOCKNUM, std::string dllfile,XMLNode *pConfig) :ThreadBase(LOCKNUM) { initPlugin(LOCKNUM,dllfile,pConfig) ; } PluginThread::~PluginThread() { } void *PluginThread::Thread() { ModuleResultBase* pRes ; FILE_LOG(logINFO) << "PluginThread starting" ; this->ThreadStarted() ; // Erstmal Bescheid geben, dass wir laufen createLock() ; while (!m_bStop) { m_signal.WaitForSignal() ; // Daten an Plugin uebergeben memLock(m_Lock) ; while (m_queue.size()>0) { FILE_LOG(logDEBUG) << "plugin processing - size=" << m_queue.size() ; pRes=m_queue.back() ; m_queue.pop_back() ; memUnlock(m_Lock) ; /* to avoid a lock caused by a crashed plugin we release our lock*/ if (m_plugin) { m_plugin->processResult(pRes) ; } delete pRes ; memLock(m_Lock) ; } memUnlock(m_Lock) ; } FILE_LOG(logINFO) << "PluginThread was stopped" ; m_plugin->quitProcessing(); return NULL; } std::string PluginThread::getPluginName() { return m_pluginName ; } void PluginThread::setPluginName(std::string name) { m_pluginName=name ; } void PluginThread::addResult(ModuleResultBase* pRes) { ModuleResultBase* localResult=new ModuleResultBase; pRes->copyTo(*localResult) ; memLock(m_Lock) ; if (m_queue.size()<MAX_QUEUESIZE) { m_queue.insert(m_queue.begin(),localResult) ; } else { FILE_LOG(logERROR) << "max plugin queue size exceeded. moduleresult not queued" ; } memUnlock(m_Lock) ; m_signal.SetSignal() ; } // ---------------------------------------- // MonitorPluginsManager MonitorPluginsManager GlobalMonitorPluginsManager ; MonitorPluginsManager& GetPluginsManager() { return (GlobalMonitorPluginsManager); } MonitorPluginsManager::MonitorPluginsManager() { // FILE_LOG(logINFO) << "PluginManager erstellt" ; if ( memLockCreate( 12348, & m_MemLock) < 0) { ThrowMonitorException("PluginManager: memLockCreate failed") ; } m_bStop=false ; } bool MonitorPluginsManager::loadScriptFilter(std::string pluginFilterFileName) { #ifdef LUA m_bUseLUAScript=false ; #endif if (! pluginFilterFileName.empty()) { #ifdef LUA // LUA TEST try { L = lua_open() ; luaL_openlibs(L) ; if(luaL_loadfile(L, pluginFilterFileName.c_str())) { throw std::string(std::string(lua_tostring(L, -1))); } if (lua_pcall(L, 0, 0, 0)) { FILE_LOG(logERROR) << "LUA test fehlgeschlagen" << std::endl ; } m_bUseLUAScript=true ; FILE_LOG(logINFO) << "Successfully loaded LUA filter: " << pluginFilterFileName ; } catch (const std::string &e) { FILE_LOG(logERROR) << "Error loading lua dispatcher script: " << e; } return m_bUseLUAScript ; #endif } return false ; } MonitorPluginsManager::~MonitorPluginsManager() { #ifdef LUA if (L!=NULL) { lua_close(L) ; } #endif } bool MonitorPluginsManager::addModule(PluginThread* pThread) { m_Modules.push_back(pThread) ; return true ; } bool MonitorPluginsManager::removeModule(PluginThread* pThread) { return false ; } bool MonitorPluginsManager::dispatchResult(ModuleResultBase *pRes) { tMonitorPluginThreadVector::iterator i ; #ifdef LUA char eins[255],zwei[255] ; #endif for (i= m_Modules.begin(); i< m_Modules.end(); i++) { m_bSkipDispatching=false ; // erstmal ggf. LUA Filter aufrufen #ifdef LUA if (m_bUseLUAScript==true) { int z ; /* push functions and arguments */ lua_getglobal(L, "pluginFilter"); /* function to be called */ // start array structure lua_newtable( L ); int numCount=1 ; for (ResultItemsMap::iterator iter=pRes->m_Items.begin(); iter!=pRes->m_Items.end(); ++iter) { { memset(eins,0,200) ; memset(zwei,0,200) ; strncpy(eins,iter->first.c_str(),199) ; strncpy(zwei,iter->second.c_str(),199) ; lua_pushstring( L, eins ); lua_pushstring( L, zwei ); lua_rawset( L, -3 ); numCount++ ; } } // Plugintype memset(eins,0,200) ; memset(zwei,0,200) ; strncpy(eins,"plugin_name",199) ; strncpy(zwei,(*i)->getPluginName().c_str(),199) ; lua_pushstring( L, eins ); lua_pushstring( L, zwei ); lua_rawset( L, -3 ); numCount++ ; // set the number of elements (index to the last array element) lua_pushliteral( L, "n" ); lua_pushnumber( L, numCount-1 ); lua_rawset( L, -3 ); // set the name of the array that the script will access lua_setglobal( L, "arg" ); /* do the call (2 arguments, 1 result) */ if (lua_pcall(L, 0, LUA_MULTRET, 0) != 0) { FILE_LOG(logERROR) << "Fehler beim Aufruf lua dispatcher script:" << lua_tostring(L, -1); //error(L, "error running function `f': %s", // lua_tostring(L, -1)); } /* retrieve result */ if (!lua_isnumber(L, -1)) { FILE_LOG(logERROR) << "nicht-numerische Antwort vom lua dispatcher script" ; //error(L, "function `f' must return a number"); } z = lua_tonumber(L, -1); lua_pop(L, 1); /* pop returned value */ FILE_LOG(logDEBUG1) << "lua Result (global dispatcher)" << z ; if (z==1) m_bSkipDispatching=true ; } #endif if (m_bSkipDispatching==false) { (*i)->addResult(pRes) ; } } return true ; } bool MonitorPluginsManager::loadPlugin(std::string dllfile, XMLNode *pConfig, std::string pluginName) { PluginThread* pt=new PluginThread() ; if (pt->initPlugin(4000,dllfile,pConfig)) { FILE_LOG(logDEBUG) << "startet plugin " << dllfile ; pt->Start() ; pt->setPluginName(pluginName) ; addModule(pt) ; return true ; } else { FILE_LOG(logERROR) << "DLL Factory konnte nicht initialisiert werden !" ; return false ; } } bool MonitorPluginsManager::loadPluginsFromConfigNode(XMLNode *pConfig) { // Plugins durchgehen std::string pluginName ; std::string pluginFile ; XMLNode parameterNode ; XMLNode *pParameters ; XMLNode pluginNode; // = pConfig->getChildNode("plugin",sndCard) ; FILE_LOG(logINFO) << "reading plugin configuration" ; int nPlugins=pConfig->nChildNode("plugin"); for (int plugin=0;plugin<nPlugins;++plugin) { // Plugin auslesen if (!((pluginNode=pConfig->getChildNode("plugin",plugin))).isEmpty()) { pluginName=pluginNode.getAttribute("name"); pluginFile=getNodeText(pluginNode,"file","") ; parameterNode=pluginNode.getChildNode("parameters"); FILE_LOG(logINFO) << "Plugin found: " << pluginName ; FILE_LOG(logDEBUG) << "File:" << pluginFile ; if (parameterNode.isEmpty()==false) { FILE_LOG(logDEBUG) << "found parameters" ; pParameters=¶meterNode ; } else { FILE_LOG(logDEBUG) << "no parameters found" ; pParameters=NULL; } if (pluginFile.size()>0) { loadPlugin(pluginFile,pParameters,pluginName) ; } } } return true ; }