ProcessEnumerator tracks processes properly now.
parent
bd4456b5f6
commit
ab40868b29
@ -1,135 +0,0 @@
|
|||||||
/*
|
|
||||||
www.sourceforge.net/projects/dfhack
|
|
||||||
Copyright (c) 2009 Petr Mrázek (peterix), Kenneth Ferland (Impaler[WrG]), dorf
|
|
||||||
|
|
||||||
This software is provided 'as-is', without any express or implied
|
|
||||||
warranty. In no event will the authors be held liable for any
|
|
||||||
damages arising from the use of this software.
|
|
||||||
|
|
||||||
Permission is granted to anyone to use this software for any
|
|
||||||
purpose, including commercial applications, and to alter it and
|
|
||||||
redistribute it freely, subject to the following restrictions:
|
|
||||||
|
|
||||||
1. The origin of this software must not be misrepresented; you must
|
|
||||||
not claim that you wrote the original software. If you use this
|
|
||||||
software in a product, an acknowledgment in the product documentation
|
|
||||||
would be appreciated but is not required.
|
|
||||||
|
|
||||||
2. Altered source versions must be plainly marked as such, and
|
|
||||||
must not be misrepresented as being the original software.
|
|
||||||
|
|
||||||
3. This notice may not be removed or altered from any source
|
|
||||||
distribution.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "Internal.h"
|
|
||||||
#include "dfhack/DFProcessEnumerator.h"
|
|
||||||
#include "dfhack/DFProcess.h"
|
|
||||||
#include "dfhack/DFMemInfo.h"
|
|
||||||
#include "dfhack/DFMemInfoManager.h"
|
|
||||||
#include <sys/shm.h>
|
|
||||||
#include <sys/types.h>
|
|
||||||
#include <sys/ipc.h>
|
|
||||||
#include <time.h>
|
|
||||||
#include "shms.h"
|
|
||||||
|
|
||||||
using namespace DFHack;
|
|
||||||
|
|
||||||
class DFHack::ProcessEnumerator::Private
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
Private(){};
|
|
||||||
MemInfoManager *meminfo;
|
|
||||||
std::vector<Process *> processes;
|
|
||||||
};
|
|
||||||
|
|
||||||
bool ProcessEnumerator::findProcessess()
|
|
||||||
{
|
|
||||||
DIR *dir_p;
|
|
||||||
struct dirent *dir_entry_p;
|
|
||||||
// Open /proc/ directory
|
|
||||||
dir_p = opendir("/proc/");
|
|
||||||
// Reading /proc/ entries
|
|
||||||
while(NULL != (dir_entry_p = readdir(dir_p)))
|
|
||||||
{
|
|
||||||
// Only PID folders (numbers)
|
|
||||||
if (strspn(dir_entry_p->d_name, "0123456789") != strlen(dir_entry_p->d_name))
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
Process *p1 = new SHMProcess(atoi(dir_entry_p->d_name),d->meminfo->meminfo);
|
|
||||||
if(p1->isIdentified())
|
|
||||||
{
|
|
||||||
d->processes.push_back(p1);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
delete p1;
|
|
||||||
}
|
|
||||||
Process *p2 = new NormalProcess(atoi(dir_entry_p->d_name),d->meminfo->meminfo);
|
|
||||||
if(p2->isIdentified())
|
|
||||||
{
|
|
||||||
d->processes.push_back(p2);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
delete p2;
|
|
||||||
}
|
|
||||||
Process *p3 = new WineProcess(atoi(dir_entry_p->d_name),d->meminfo->meminfo);
|
|
||||||
if(p3->isIdentified())
|
|
||||||
{
|
|
||||||
d->processes.push_back(p3);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
delete p3;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
closedir(dir_p);
|
|
||||||
// return value depends on if we found some DF processes
|
|
||||||
if(d->processes.size())
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32_t ProcessEnumerator::size()
|
|
||||||
{
|
|
||||||
return d->processes.size();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
Process * ProcessEnumerator::operator[](uint32_t index)
|
|
||||||
{
|
|
||||||
assert(index < d->processes.size());
|
|
||||||
return d->processes[index];
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
ProcessEnumerator::ProcessEnumerator( string path_to_xml )
|
|
||||||
: d(new Private())
|
|
||||||
{
|
|
||||||
d->meminfo = new MemInfoManager(path_to_xml);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ProcessEnumerator::purge()
|
|
||||||
{
|
|
||||||
for(uint32_t i = 0;i < d->processes.size();i++)
|
|
||||||
{
|
|
||||||
delete d->processes[i];
|
|
||||||
}
|
|
||||||
d->processes.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
ProcessEnumerator::~ProcessEnumerator()
|
|
||||||
{
|
|
||||||
// delete all processes
|
|
||||||
purge();
|
|
||||||
delete d->meminfo;
|
|
||||||
delete d;
|
|
||||||
}
|
|
@ -1,147 +0,0 @@
|
|||||||
/*
|
|
||||||
www.sourceforge.net/projects/dfhack
|
|
||||||
Copyright (c) 2009 Petr Mrázek (peterix), Kenneth Ferland (Impaler[WrG]), dorf
|
|
||||||
|
|
||||||
This software is provided 'as-is', without any express or implied
|
|
||||||
warranty. In no event will the authors be held liable for any
|
|
||||||
damages arising from the use of this software.
|
|
||||||
|
|
||||||
Permission is granted to anyone to use this software for any
|
|
||||||
purpose, including commercial applications, and to alter it and
|
|
||||||
redistribute it freely, subject to the following restrictions:
|
|
||||||
|
|
||||||
1. The origin of this software must not be misrepresented; you must
|
|
||||||
not claim that you wrote the original software. If you use this
|
|
||||||
software in a product, an acknowledgment in the product documentation
|
|
||||||
would be appreciated but is not required.
|
|
||||||
|
|
||||||
2. Altered source versions must be plainly marked as such, and
|
|
||||||
must not be misrepresented as being the original software.
|
|
||||||
|
|
||||||
3. This notice may not be removed or altered from any source
|
|
||||||
distribution.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "Internal.h"
|
|
||||||
#include "dfhack/DFProcessEnumerator.h"
|
|
||||||
#include "dfhack/DFProcess.h"
|
|
||||||
#include "dfhack/DFMemInfo.h"
|
|
||||||
#include "dfhack/DFMemInfoManager.h"
|
|
||||||
using namespace DFHack;
|
|
||||||
|
|
||||||
class DFHack::ProcessEnumerator::Private
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
Private(){};
|
|
||||||
MemInfoManager *meminfo;
|
|
||||||
std::vector<Process *> processes;
|
|
||||||
};
|
|
||||||
|
|
||||||
// some magic - will come in handy when we start doing debugger stuff on Windows
|
|
||||||
bool EnableDebugPriv()
|
|
||||||
{
|
|
||||||
bool bRET = FALSE;
|
|
||||||
TOKEN_PRIVILEGES tp;
|
|
||||||
HANDLE hToken;
|
|
||||||
|
|
||||||
if (LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &tp.Privileges[0].Luid))
|
|
||||||
{
|
|
||||||
if (OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &hToken))
|
|
||||||
{
|
|
||||||
if (hToken != INVALID_HANDLE_VALUE)
|
|
||||||
{
|
|
||||||
tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
|
|
||||||
tp.PrivilegeCount = 1;
|
|
||||||
if (AdjustTokenPrivileges(hToken, FALSE, &tp, 0, 0, 0))
|
|
||||||
{
|
|
||||||
bRET = TRUE;
|
|
||||||
}
|
|
||||||
CloseHandle(hToken);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return bRET;
|
|
||||||
}
|
|
||||||
|
|
||||||
// WINDOWS version of the process finder
|
|
||||||
bool ProcessEnumerator::findProcessess()
|
|
||||||
{
|
|
||||||
// Get the list of process identifiers.
|
|
||||||
DWORD ProcArray[2048], memoryNeeded, numProccesses;
|
|
||||||
//EnableDebugPriv();
|
|
||||||
if ( !EnumProcesses( ProcArray, sizeof(ProcArray), &memoryNeeded ) )
|
|
||||||
{
|
|
||||||
cout << "EnumProcesses fail'd" << endl;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Calculate how many process identifiers were returned.
|
|
||||||
numProccesses = memoryNeeded / sizeof(DWORD);
|
|
||||||
EnableDebugPriv();
|
|
||||||
|
|
||||||
// iterate through processes
|
|
||||||
for ( int i = 0; i < (int)numProccesses; i++ )
|
|
||||||
{
|
|
||||||
Process *p = new SHMProcess(ProcArray[i],d->meminfo->meminfo);
|
|
||||||
if(p->isIdentified())
|
|
||||||
{
|
|
||||||
d->processes.push_back(p);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
delete p;
|
|
||||||
p = 0;
|
|
||||||
}
|
|
||||||
p = new NormalProcess(ProcArray[i],d->meminfo->meminfo);
|
|
||||||
if(p->isIdentified())
|
|
||||||
{
|
|
||||||
d->processes.push_back(p);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
delete p;
|
|
||||||
p = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if(d->processes.size())
|
|
||||||
return true;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32_t ProcessEnumerator::size()
|
|
||||||
{
|
|
||||||
return d->processes.size();
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
Process * ProcessEnumerator::operator[](uint32_t index)
|
|
||||||
{
|
|
||||||
assert(index < d->processes.size());
|
|
||||||
return d->processes[index];
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
ProcessEnumerator::ProcessEnumerator( string path_to_xml )
|
|
||||||
: d(new Private())
|
|
||||||
{
|
|
||||||
d->meminfo = new MemInfoManager(path_to_xml);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ProcessEnumerator::purge()
|
|
||||||
{
|
|
||||||
for(uint32_t i = 0;i < d->processes.size();i++)
|
|
||||||
{
|
|
||||||
delete d->processes[i];
|
|
||||||
}
|
|
||||||
d->processes.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
ProcessEnumerator::~ProcessEnumerator()
|
|
||||||
{
|
|
||||||
// delete all processes
|
|
||||||
purge();
|
|
||||||
delete d->meminfo;
|
|
||||||
delete d;
|
|
||||||
}
|
|
@ -0,0 +1,318 @@
|
|||||||
|
/*
|
||||||
|
www.sourceforge.net/projects/dfhack
|
||||||
|
Copyright (c) 2009 Petr Mrázek (peterix), Kenneth Ferland (Impaler[WrG]), dorf
|
||||||
|
|
||||||
|
This software is provided 'as-is', without any express or implied
|
||||||
|
warranty. In no event will the authors be held liable for any
|
||||||
|
damages arising from the use of this software.
|
||||||
|
|
||||||
|
Permission is granted to anyone to use this software for any
|
||||||
|
purpose, including commercial applications, and to alter it and
|
||||||
|
redistribute it freely, subject to the following restrictions:
|
||||||
|
|
||||||
|
1. The origin of this software must not be misrepresented; you must
|
||||||
|
not claim that you wrote the original software. If you use this
|
||||||
|
software in a product, an acknowledgment in the product documentation
|
||||||
|
would be appreciated but is not required.
|
||||||
|
|
||||||
|
2. Altered source versions must be plainly marked as such, and
|
||||||
|
must not be misrepresented as being the original software.
|
||||||
|
|
||||||
|
3. This notice may not be removed or altered from any source
|
||||||
|
distribution.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "Internal.h"
|
||||||
|
#include "dfhack/DFProcessEnumerator.h"
|
||||||
|
#include "dfhack/DFProcess.h"
|
||||||
|
#include "dfhack/DFMemInfo.h"
|
||||||
|
#include "dfhack/DFMemInfoManager.h"
|
||||||
|
|
||||||
|
using namespace DFHack;
|
||||||
|
|
||||||
|
typedef std::vector<Process *> PROC_V;
|
||||||
|
typedef std::map<ProcessID, Process*> PID2PROC;
|
||||||
|
|
||||||
|
class DFHack::ProcessEnumerator::Private
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Private(){};
|
||||||
|
MemInfoManager *meminfo;
|
||||||
|
PROC_V Processes;
|
||||||
|
PID2PROC ProcMap;
|
||||||
|
Process *GetProcessObject(ProcessID ID);
|
||||||
|
void EnumPIDs (vector <ProcessID> &PIDs);
|
||||||
|
};
|
||||||
|
|
||||||
|
#ifdef LINUX_BUILD
|
||||||
|
//FIXME: wasteful
|
||||||
|
Process *ProcessEnumerator::Private::GetProcessObject(ProcessID ID)
|
||||||
|
{
|
||||||
|
|
||||||
|
Process *p1 = new SHMProcess(ID.pid,meminfo->meminfo);
|
||||||
|
if(p1->isIdentified())
|
||||||
|
return p1;
|
||||||
|
else
|
||||||
|
delete p1;
|
||||||
|
|
||||||
|
Process *p2 = new NormalProcess(ID.pid,meminfo->meminfo);
|
||||||
|
if(p2->isIdentified())
|
||||||
|
return p2;
|
||||||
|
else
|
||||||
|
delete p2;
|
||||||
|
|
||||||
|
Process *p3 = new WineProcess(ID.pid,meminfo->meminfo);
|
||||||
|
if(p3->isIdentified())
|
||||||
|
return p3;
|
||||||
|
else
|
||||||
|
delete p3;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ProcessEnumerator::Private::EnumPIDs (vector <ProcessID> &PIDs)
|
||||||
|
{
|
||||||
|
DIR *dir_p;
|
||||||
|
struct dirent *dir_entry_p;
|
||||||
|
struct stat st;
|
||||||
|
char fullname[512];
|
||||||
|
fullname[0] = 0;
|
||||||
|
PIDs.clear(); // make sure the vector is clear
|
||||||
|
|
||||||
|
// Open /proc/ directory
|
||||||
|
dir_p = opendir("/proc/");
|
||||||
|
// Reading /proc/ entries
|
||||||
|
while(NULL != (dir_entry_p = readdir(dir_p)))
|
||||||
|
{
|
||||||
|
// Only PID folders (numbers)
|
||||||
|
if (strspn(dir_entry_p->d_name, "0123456789") != strlen(dir_entry_p->d_name))
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
sprintf(fullname, "/proc/%s", dir_entry_p->d_name);
|
||||||
|
int ierr = stat (fullname, &st);
|
||||||
|
if (ierr != 0)
|
||||||
|
{
|
||||||
|
printf("Cannot stat %s: ierr= %d\n", fullname, ierr);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
uint64_t Pnum = atoi(dir_entry_p->d_name);
|
||||||
|
uint64_t ctime = st.st_ctime;
|
||||||
|
PIDs.push_back(ProcessID(ctime,Pnum));
|
||||||
|
}
|
||||||
|
closedir(dir_p);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef LINUX_BUILD
|
||||||
|
Process *ProcessEnumerator::Private::GetProcessObject(ProcessID ID)
|
||||||
|
{
|
||||||
|
|
||||||
|
Process *p1 = new SHMProcess(ID.pid,meminfo->meminfo);
|
||||||
|
if(p1->isIdentified())
|
||||||
|
return p1;
|
||||||
|
else
|
||||||
|
delete p1;
|
||||||
|
|
||||||
|
Process *p2 = new NormalProcess(ID.pid,meminfo->meminfo);
|
||||||
|
if(p2->isIdentified())
|
||||||
|
return p2;
|
||||||
|
else
|
||||||
|
delete p2;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
// some magic - will come in handy when we start doing debugger stuff on Windows
|
||||||
|
bool EnableDebugPriv()
|
||||||
|
{
|
||||||
|
bool bRET = FALSE;
|
||||||
|
TOKEN_PRIVILEGES tp;
|
||||||
|
HANDLE hToken;
|
||||||
|
|
||||||
|
if (LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &tp.Privileges[0].Luid))
|
||||||
|
{
|
||||||
|
if (OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &hToken))
|
||||||
|
{
|
||||||
|
if (hToken != INVALID_HANDLE_VALUE)
|
||||||
|
{
|
||||||
|
tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
|
||||||
|
tp.PrivilegeCount = 1;
|
||||||
|
if (AdjustTokenPrivileges(hToken, FALSE, &tp, 0, 0, 0))
|
||||||
|
{
|
||||||
|
bRET = TRUE;
|
||||||
|
}
|
||||||
|
CloseHandle(hToken);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return bRET;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Convert Windows FileTime structs to POSIX timestamp
|
||||||
|
// from http://frenk.wordpress.com/2009/12/14/convert-filetime-to-unix-timestamp/
|
||||||
|
uint64_t FileTime_to_POSIX(FILETIME ft)
|
||||||
|
{
|
||||||
|
// takes the last modified date
|
||||||
|
LARGE_INTEGER date, adjust;
|
||||||
|
date.HighPart = ft.dwHighDateTime;
|
||||||
|
date.LowPart = ft.dwLowDateTime;
|
||||||
|
|
||||||
|
// 100-nanoseconds = milliseconds * 10000
|
||||||
|
adjust.QuadPart = 11644473600000 * 10000;
|
||||||
|
|
||||||
|
// removes the diff between 1970 and 1601
|
||||||
|
date.QuadPart -= adjust.QuadPart;
|
||||||
|
|
||||||
|
// converts back from 100-nanoseconds to seconds
|
||||||
|
return date.QuadPart / 10000000;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ProcessEnumerator::Private::EnumPIDs (vector <ProcessID> &PIDs)
|
||||||
|
{
|
||||||
|
FILETIME ftCreate, ftExit, ftKernel, ftUser;
|
||||||
|
|
||||||
|
PIDs.clear(); // make sure the vector is clear
|
||||||
|
|
||||||
|
// Get the list of process identifiers.
|
||||||
|
DWORD ProcArray[2048], memoryNeeded, numProccesses;
|
||||||
|
//EnableDebugPriv();
|
||||||
|
if ( !EnumProcesses( ProcArray, sizeof(ProcArray), &memoryNeeded ) )
|
||||||
|
{
|
||||||
|
cout << "EnumProcesses fail'd" << endl;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// Calculate how many process identifiers were returned.
|
||||||
|
numProccesses = memoryNeeded / sizeof(DWORD);
|
||||||
|
EnableDebugPriv();
|
||||||
|
// iterate through processes
|
||||||
|
for ( int i = 0; i < (int)numProccesses; i++ )
|
||||||
|
{
|
||||||
|
HANDLE proc = OpenProcess (PROCESS_QUERY_INFORMATION, false, ProcArray[i]);
|
||||||
|
if(!proc)
|
||||||
|
continue;
|
||||||
|
if(GetProcessTimes(proc, &ftCreate, &ftExit, &ftKernel, &ftUser))
|
||||||
|
{
|
||||||
|
uint64_t ctime = FileTime_to_POSIX(ftCreate);
|
||||||
|
uint64_t Pnum = ProcArray[i];
|
||||||
|
PIDs.push_back(ProcessID(ctime,Pnum));
|
||||||
|
}
|
||||||
|
CloseHandle(proc);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
bool ProcessEnumerator::Refresh( PROC_V * invalidated_processes)
|
||||||
|
{
|
||||||
|
// PIDs to process
|
||||||
|
vector <ProcessID> PIDs;
|
||||||
|
// this will be the new process map
|
||||||
|
PID2PROC temporary;
|
||||||
|
// clear the vector other access
|
||||||
|
d->Processes.clear();
|
||||||
|
if(invalidated_processes)
|
||||||
|
invalidated_processes->clear();
|
||||||
|
|
||||||
|
d->EnumPIDs(PIDs);
|
||||||
|
|
||||||
|
for(uint64_t i = 0; i < PIDs.size();i++)
|
||||||
|
{
|
||||||
|
ProcessID & PID = PIDs[i];
|
||||||
|
// check if we know about the OS process already
|
||||||
|
PID2PROC::iterator found= d->ProcMap.find(PID);
|
||||||
|
if( found != d->ProcMap.end())
|
||||||
|
{
|
||||||
|
// we do
|
||||||
|
// check if it does have a DFHack Process object associated with it
|
||||||
|
Process * p = (*found).second;
|
||||||
|
if(p)
|
||||||
|
{
|
||||||
|
// add it back to the vector we export
|
||||||
|
d->Processes.push_back(p);
|
||||||
|
}
|
||||||
|
// remove the OS Process from ProcMap
|
||||||
|
d->ProcMap.erase(found);
|
||||||
|
// add the OS Process to what will be the new ProcMap
|
||||||
|
temporary[PID] = p;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// an OS process we don't know yet!
|
||||||
|
// try to make a DFHack Process object for it
|
||||||
|
if(Process*p = d->GetProcessObject(PID))
|
||||||
|
{
|
||||||
|
// allright. this is something that can be used
|
||||||
|
d->Processes.push_back(p);
|
||||||
|
temporary[PID] = p;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// just a process. we track it anyway. Why not.
|
||||||
|
temporary[PID] = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// now the vector we export is filled again and a temporary map with valid processes is created.
|
||||||
|
// we iterate over the old Process map and destroy all the processes that are dead.
|
||||||
|
for(PID2PROC::const_iterator idx = d->ProcMap.begin(); idx != d->ProcMap.end();++idx)
|
||||||
|
{
|
||||||
|
Process * p = (*idx).second;
|
||||||
|
if(p)
|
||||||
|
{
|
||||||
|
if(invalidated_processes)
|
||||||
|
{
|
||||||
|
invalidated_processes->push_back(p);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
delete p;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
d->ProcMap.swap(temporary);
|
||||||
|
// return value depends on if we found some DF processes
|
||||||
|
if(d->Processes.size())
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ProcessEnumerator::findProcessess()
|
||||||
|
{
|
||||||
|
return Refresh();
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t ProcessEnumerator::size()
|
||||||
|
{
|
||||||
|
return d->Processes.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Process * ProcessEnumerator::operator[](uint32_t index)
|
||||||
|
{
|
||||||
|
assert(index < d->Processes.size());
|
||||||
|
return d->Processes[index];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
ProcessEnumerator::ProcessEnumerator( string path_to_xml )
|
||||||
|
: d(new Private())
|
||||||
|
{
|
||||||
|
d->meminfo = new MemInfoManager(path_to_xml);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ProcessEnumerator::purge()
|
||||||
|
{
|
||||||
|
for(uint32_t i = 0;i < d->Processes.size();i++)
|
||||||
|
{
|
||||||
|
delete d->Processes[i];
|
||||||
|
}
|
||||||
|
d->ProcMap.clear();
|
||||||
|
d->Processes.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
ProcessEnumerator::~ProcessEnumerator()
|
||||||
|
{
|
||||||
|
// delete all processes
|
||||||
|
purge();
|
||||||
|
delete d->meminfo;
|
||||||
|
delete d;
|
||||||
|
}
|
@ -0,0 +1,57 @@
|
|||||||
|
// Demonstrates the use of ProcessEnumerator
|
||||||
|
// queries the Enumerator for all DF Processes on user input. Prints them to the terminal.
|
||||||
|
// also tracks processes that were invalidated
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
#include <climits>
|
||||||
|
#include <vector>
|
||||||
|
#include <ctime>
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
#include <DFHack.h>
|
||||||
|
#include <dfhack/DFProcessEnumerator.h>
|
||||||
|
using namespace DFHack;
|
||||||
|
#ifndef LINUX_BUILD
|
||||||
|
#endif
|
||||||
|
int main (void)
|
||||||
|
{
|
||||||
|
vector<Process*> inval;
|
||||||
|
ProcessEnumerator Penum("Memory.xml");
|
||||||
|
memory_info * mem;
|
||||||
|
for(int cnt = 0; cnt < 100; cnt++)
|
||||||
|
{
|
||||||
|
// make the ProcessEnumerator update its list of Processes
|
||||||
|
// by passing the pointer to 'inval', we make it export expired
|
||||||
|
// processes instead of destroying them outright
|
||||||
|
// (processes expire when the OS kills them for whatever reason)
|
||||||
|
Penum.Refresh(&inval);
|
||||||
|
int nProc = Penum.size();
|
||||||
|
int nInval = inval.size();
|
||||||
|
|
||||||
|
cout << "Processes:" << endl;
|
||||||
|
for(int i = 0; i < nProc; i++)
|
||||||
|
{
|
||||||
|
mem = Penum[i]->getDescriptor();
|
||||||
|
cout << "DF instance: " << Penum[i]->getPID()
|
||||||
|
<< ", " << mem->getVersion() << endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
cout << "Invalidated:" << endl;
|
||||||
|
for(int i = 0; i < nInval; i++)
|
||||||
|
{
|
||||||
|
mem = inval[i]->getDescriptor();
|
||||||
|
cout << "DF instance: " << inval[i]->getPID()
|
||||||
|
<< ", " << mem->getVersion() << endl;
|
||||||
|
// we own the expired process, we must take care of freeing its resources
|
||||||
|
delete inval[i];
|
||||||
|
}
|
||||||
|
cout << "<-* Press Enter to refresh *->" << endl << endl;
|
||||||
|
cin.ignore();
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifndef LINUX_BUILD
|
||||||
|
cout << "Done. Press any key to continue" << endl;
|
||||||
|
cin.ignore();
|
||||||
|
#endif
|
||||||
|
return 0;
|
||||||
|
}
|
Loading…
Reference in New Issue