|
|
|
@ -41,23 +41,90 @@ distribution.
|
|
|
|
|
using namespace DFHack;
|
|
|
|
|
namespace DFHack
|
|
|
|
|
{
|
|
|
|
|
class DFContextMgrPrivate
|
|
|
|
|
class ContextManager::Private
|
|
|
|
|
{
|
|
|
|
|
public:
|
|
|
|
|
DFContextMgrPrivate(){};
|
|
|
|
|
~DFContextMgrPrivate(){};
|
|
|
|
|
Private(){};
|
|
|
|
|
~Private(){};
|
|
|
|
|
string xml; // path to xml
|
|
|
|
|
vector <Context *> contexts;
|
|
|
|
|
ProcessEnumerator * pEnum;
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
class DFHack::BadContexts::Private
|
|
|
|
|
{
|
|
|
|
|
public:
|
|
|
|
|
Private(){};
|
|
|
|
|
vector <Context *> bad;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
BadContexts::BadContexts():d(new Private()){}
|
|
|
|
|
|
|
|
|
|
BadContexts::~BadContexts()
|
|
|
|
|
{
|
|
|
|
|
clear();
|
|
|
|
|
delete d;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool BadContexts::Contains(Process* p)
|
|
|
|
|
{
|
|
|
|
|
for(int i = 0; i < d->bad.size(); i++)
|
|
|
|
|
{
|
|
|
|
|
if((d->bad[i])->getProcess() == p)
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool BadContexts::Contains(Context* c)
|
|
|
|
|
{
|
|
|
|
|
for(int i = 0; i < d->bad.size(); i++)
|
|
|
|
|
{
|
|
|
|
|
if(d->bad[i] == c)
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
uint32_t BadContexts::size()
|
|
|
|
|
{
|
|
|
|
|
return d->bad.size();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void BadContexts::clear()
|
|
|
|
|
{
|
|
|
|
|
for(int i = 0; i < d->bad.size(); i++)
|
|
|
|
|
{
|
|
|
|
|
// delete both Process and Context!
|
|
|
|
|
// process has to be deleted after context, because Context does some
|
|
|
|
|
// cleanup on delete (detach, etc.)
|
|
|
|
|
Process * to_kill = d->bad[i]->getProcess();
|
|
|
|
|
delete d->bad[i];
|
|
|
|
|
delete to_kill;
|
|
|
|
|
}
|
|
|
|
|
d->bad.clear();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void BadContexts::push_back(Context* c)
|
|
|
|
|
{
|
|
|
|
|
if(c)
|
|
|
|
|
d->bad.push_back(c);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Context * BadContexts::operator[](uint32_t index)
|
|
|
|
|
{
|
|
|
|
|
if(index < d->bad.size())
|
|
|
|
|
return d->bad[index];
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ContextManager::ContextManager (const string path_to_xml) : d (new DFContextMgrPrivate())
|
|
|
|
|
ContextManager::ContextManager (const string path_to_xml) : d (new Private())
|
|
|
|
|
{
|
|
|
|
|
d->pEnum = 0;
|
|
|
|
|
d->xml = QUOT (MEMXML_DATA_PATH);
|
|
|
|
|
d->xml += "/";
|
|
|
|
|
d->xml += path_to_xml;
|
|
|
|
|
d->pEnum = new ProcessEnumerator(d->xml);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ContextManager::~ContextManager()
|
|
|
|
@ -66,26 +133,76 @@ ContextManager::~ContextManager()
|
|
|
|
|
delete d;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
uint32_t ContextManager::Refresh()
|
|
|
|
|
uint32_t ContextManager::Refresh( BadContexts* bad_contexts )
|
|
|
|
|
{
|
|
|
|
|
purge();
|
|
|
|
|
if(d->pEnum != 0)
|
|
|
|
|
d->pEnum = new ProcessEnumerator(d->xml);
|
|
|
|
|
else
|
|
|
|
|
// handle expired processes, remove stale Contexts
|
|
|
|
|
{
|
|
|
|
|
delete d->pEnum;
|
|
|
|
|
d->pEnum = new ProcessEnumerator(d->xml);
|
|
|
|
|
BadProcesses expired;
|
|
|
|
|
// get new list od living and expired Process objects
|
|
|
|
|
d->pEnum->Refresh(&expired);
|
|
|
|
|
|
|
|
|
|
// scan expired, kill contexts if necessary
|
|
|
|
|
vector <Context*>::iterator it = d->contexts.begin();;
|
|
|
|
|
while(it != d->contexts.end())
|
|
|
|
|
{
|
|
|
|
|
Process * test = (*it)->getProcess();
|
|
|
|
|
if(expired.Contains(test))
|
|
|
|
|
{
|
|
|
|
|
// ok. we have an expired context here.
|
|
|
|
|
if(!bad_contexts)
|
|
|
|
|
{
|
|
|
|
|
// with nowhere to put the context, we have to destroy it
|
|
|
|
|
delete *it;
|
|
|
|
|
// stop tracking it and advance the iterator
|
|
|
|
|
it = d->contexts.erase(it);
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
// we stuff the context into bad_contexts
|
|
|
|
|
bad_contexts->push_back(*it);
|
|
|
|
|
// stop tracking it and advance the iterator
|
|
|
|
|
it = d->contexts.erase(it);
|
|
|
|
|
// remove process from the 'expired' container, it is tracked by bad_contexts now
|
|
|
|
|
// (which is responsible for freeing it).
|
|
|
|
|
expired.excise(test);
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else it++; // not expired, just advance to next one
|
|
|
|
|
}
|
|
|
|
|
// no expired contexts are in the d->contexts vector now
|
|
|
|
|
// all processes remaining in 'expired' are now destroyed along with it
|
|
|
|
|
}
|
|
|
|
|
d->pEnum->purge();
|
|
|
|
|
d->pEnum->findProcessess();
|
|
|
|
|
|
|
|
|
|
int numProcesses = d->pEnum->size();
|
|
|
|
|
int numContexts = d->contexts.size();
|
|
|
|
|
vector <Context *> newContexts;
|
|
|
|
|
// enumerate valid processes
|
|
|
|
|
for(int i = 0; i < numProcesses; i++)
|
|
|
|
|
{
|
|
|
|
|
Context * c = new Context(d->pEnum->operator[](i));
|
|
|
|
|
d->contexts.push_back(c);
|
|
|
|
|
Process * test = d->pEnum->operator[](i);
|
|
|
|
|
bool exists = false;
|
|
|
|
|
// scan context vector for this process
|
|
|
|
|
for(int j = 0; j < numContexts; j++)
|
|
|
|
|
{
|
|
|
|
|
if((d->contexts[j])->getProcess() == test)
|
|
|
|
|
{
|
|
|
|
|
// already have that one, skip
|
|
|
|
|
exists = true;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if(!exists)
|
|
|
|
|
{
|
|
|
|
|
// new process needs a new context
|
|
|
|
|
Context * c = new Context(d->pEnum->operator[](i));
|
|
|
|
|
newContexts.push_back(c);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
d->contexts.insert(d->contexts.end(), newContexts.begin(), newContexts.end());
|
|
|
|
|
return d->contexts.size();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
uint32_t ContextManager::size()
|
|
|
|
|
{
|
|
|
|
|
return d->contexts.size();
|
|
|
|
|