00001 
00012 
00013 
00014 
00015 
00016 
00017 
00018 
00019 
00020 
00021 
00022 
00023 
00024 
00025 
00026 
00027 
00028 
00029 #include "Processes.hpp"
00030 #include "../libH/Debug.hpp"
00031 #include "../libH/Exception.hpp"
00032 #include "../libH/UtilTime.hpp"
00033 #include <fstream>
00034 #include <iostream>
00035 #include <boost/filesystem/operations.hpp>
00036 #include <boost/filesystem/exception.hpp>
00037 #include <boost/tokenizer.hpp>
00038 #include <boost/lexical_cast.hpp>
00039 
00040 using namespace std;
00041 using namespace boost;
00042 using namespace boost::filesystem;
00043 using namespace H;
00044 using namespace Gizmod;
00045 
00047 
00049 
00054 #define PROC_PATH               "/proc"
00055 
00060 #define DEFAULT_UPDATE_DELAY    2500000
00061 
00063 
00065         
00066 mutex Processes::mMutexUpdate;                                    
00067 map< string, shared_ptr<Process> > Processes::mProcesses;         
00068 unsigned long Processes::mLastUpdateTime = 0;                     
00069 unsigned long Processes::mMsBetweenUpdates = DEFAULT_UPDATE_DELAY; 
00070 
00072 
00074 
00078 Processes::Processes() {
00079         
00080         isProcessRunning("");
00081 }
00082 
00086 Process::Process() {
00087         PID = -1;
00088 }
00089 
00093 Processes::~Processes() {
00094 }
00095 
00099 Process::~Process() {
00100 }
00101 
00103 
00105 
00111 int Processes::isProcessRunning(std::string ProcessName) {
00112         if (UtilTime::getTicks() - mLastUpdateTime >= mMsBetweenUpdates)
00113                 updateProcessTree();
00114         
00115         
00116         mutex::scoped_lock lock(mMutexUpdate);
00117         
00118         shared_ptr<Process> pProcess = mProcesses[ProcessName];
00119         if ( (!pProcess) || (pProcess->State == "Z") )
00120                 return -1;
00121         else
00122                 return pProcess->PID;
00123 }
00124 
00129 void Processes::setTimeBetweenUpdates(float Seconds) {
00130         mMsBetweenUpdates = (unsigned long) (Seconds * 1000000.0f);
00131 }
00132 
00136 void Processes::updateProcessTree() {
00137         cdbg5 << "Building Process Tree" << endl;
00138         if (!filesystem::exists(path(PROC_PATH))) {
00139                 cdbg << "Error Building Process Tree!" << endl;
00140                 return;
00141         }
00142         
00143         
00144         mutex::scoped_lock lock(mMutexUpdate);
00145         
00146         
00147         mProcesses.clear();
00148                 
00149         
00150         typedef boost::tokenizer<boost::char_separator<char> > tokenizer;
00151         char_separator<char> Separators(" ");
00152         
00153         
00154         
00155         directory_iterator endItr;
00156         for (directory_iterator iter(PROC_PATH); iter != endItr; iter ++) {
00157                 string StatPath = iter->string() + "/stat";
00158                 try {
00159                         if ( (filesystem::is_directory(*iter)) && (filesystem::exists(path(StatPath))) ) {
00160                                 ifstream StatFile(StatPath.c_str());
00161                                 if (!StatFile.is_open())
00162                                         continue;
00163                                 string Line;
00164                                 getline(StatFile, Line);
00165                                 tokenizer tok(Line, Separators);
00166                                 shared_ptr<Process> pProcess = shared_ptr<Process>(new Process);
00167                                 int count = 0;
00168                                 for(tokenizer::iterator iter = tok.begin(); iter!= tok.end(); iter ++, count ++) {
00169                                         bool BreakFor = false;
00170                                         switch (count) {
00171                                         case 0:
00172                                                 try {
00173                                                         pProcess->PID = lexical_cast<int>(*iter);
00174                                                 } catch (bad_lexical_cast const & e) {
00175                                                         
00176                                                         BreakFor = true;
00177                                                 }
00178                                                 break;
00179                                         case 1:
00180                                                 pProcess->Name = iter->substr(1, iter->length() - 2);
00181                                                 break;
00182                                         case 2:
00183                                                 pProcess->State = *iter;
00184                                                 mProcesses.insert(make_pair(pProcess->Name, pProcess));
00185                                                 BreakFor = true;
00186                                                 break;
00187                                         }
00188                                         
00189                                         if (BreakFor)
00190                                                 break;
00191                                 }
00192                         }
00193                 } catch (filesystem_error const & e) {
00194                         
00195                 }
00196         }
00197         
00198         
00199         mLastUpdateTime = UtilTime::getTicks(); 
00200 }