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 }