libGizmod/Processes.cpp

Go to the documentation of this file.
00001 
00012 /*
00013   
00014   Copyright (c) 2007, Tim Burrell
00015   Licensed under the Apache License, Version 2.0 (the "License");
00016   you may not use this file except in compliance with the License.
00017   You may obtain a copy of the License at 
00018 
00019         http://www.apache.org/licenses/LICENSE-2.0
00020 
00021   Unless required by applicable law or agreed to in writing, software
00022   distributed under the License is distributed on an "AS IS" BASIS,
00023   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00024   See the License for the specific language governing permissions and 
00025   limitations under the License. 
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 // Typedef's / defines
00049 
00054 #define PROC_PATH               "/proc"
00055 
00060 #define DEFAULT_UPDATE_DELAY    2500000
00061 
00063 // Statics 
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 // Construction
00074 
00078 Processes::Processes() {
00079         // update the process tree if necessary
00080         isProcessRunning("");
00081 }
00082 
00086 Process::Process() {
00087         PID = -1;
00088 }
00089 
00093 Processes::~Processes() {
00094 }
00095 
00099 Process::~Process() {
00100 }
00101 
00103 // Class Body
00105 
00111 int Processes::isProcessRunning(std::string ProcessName) {
00112         if (UtilTime::getTicks() - mLastUpdateTime >= mMsBetweenUpdates)
00113                 updateProcessTree();
00114         
00115         // lock the processes
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         // lock the processes
00144         mutex::scoped_lock lock(mMutexUpdate);
00145         
00146         // clear out the process list
00147         mProcesses.clear();
00148                 
00149         // create some data structures for parsing the info
00150         typedef boost::tokenizer<boost::char_separator<char> > tokenizer;
00151         char_separator<char> Separators(" ");
00152         
00153         // now register the event nodes
00154         // get a file listing
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                                                         // unable to convert
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                         // no worries, just continue
00195                 }
00196         }
00197         
00198         // update the time
00199         mLastUpdateTime = UtilTime::getTicks(); 
00200 }

Generated on Wed Nov 7 10:04:16 2007 for gizmod by  doxygen 1.5.3