ParseRunnables.cpp
// ParseRunnables.cpp
//
// Author David Barrett-Lennard
// (C)opyright Cedanet Pty Ltd 2009
@import "Ceda/cxCedaScript/cxCedaScript.h"
@import "Ceda/cxPersistStore/pref.h"
@import "Ceda/cxPersistStore/IPrefVisitor.h"
@import "Ceda/cxPersistStore/xmap.h"
@import "Ceda/cxObject/Object.h"
@import "Ceda/cxObject/IObjectVisitor.h"
@import "Ceda/cxObject/WCSpace.h"
@import "Ceda/cxObject/PrintReflectedVariable.h"
#include "Ceda/cxUtils/Tracer.h"
#include "Ceda/cxUtils/xdeque.h"
#include "Ceda/cxUtils/MsWindows.h"
#include "Ceda/cxUtils/HPTime.h"
#include <assert.h>
namespace ceda
{
$interface+ IRunnable : IObject
{
void Start();
void Stop();
};
void ParseRunnables(ExpressionParser& parser)
{
xdeque< ptr<IRunnable> > L;
parser.ParseGivenToken(TOKEN_LEFT_CURLY, "{");
while(1)
{
if (parser.GetTokenType() == TOKEN_LEFT_CURLY)
{
ParseRunnables(parser);
}
else if (parser.GetTokenType() == TOKEN_RIGHT_CURLY)
{
parser.ReadNextToken();
break;
}
else
{
ptr<IRunnable> r;
{
CSpaceLock lock;
ptr<IObject> p = ParseDataSource(parser);
r = qicast<IRunnable>(p);
cxAssert(r);
AddGcRoot(r);
}
L.push_back(r);
r->Start();
}
}
while(!L.empty())
{
ptr<IRunnable> r = L.back();
L.pop_back();
r->Stop();
{
CSpaceLock lock;
RemoveGcRoot(r);
}
}
}
} // namespace ceda
namespace ParseRunnableEx
{
const int MAGIC = 0x0138fe5d;
$struct+ X isa ceda::IRunnable :
model
{
string8 name;
}
{
X() : magic(MAGIC), prevcspace(NULL), cspace(NULL) {}
~X()
{
cxAssert(magic == MAGIC);
magic = 0;
}
void Start()
{
cxAssert(magic == MAGIC);
Tracer() << "Start " << name << '\n';
ceda::IndentTrace(2);
Sleep(50);
prevcspace = ceda::GetThreadPtr<ceda::CSpace>();
cspace = ceda::CreateCSpace(10);
ceda::SetThreadPtr<ceda::CSpace>(cspace);
}
void Stop()
{
cxAssert(cspace == ceda::GetThreadPtr<ceda::CSpace>());
ceda::Destroy(cspace);
ceda::SetThreadPtr<ceda::CSpace>(prevcspace);
Sleep(50);
ceda::IndentTrace(-2);
Tracer() << "Stop " << name << '\n';
cxAssert(magic == MAGIC);
}
int magic; // Used to check for destruction while object is still being used.
ceda::CSpace* prevcspace;
ceda::CSpace* cspace;
};
/*
Output is:
Start a
Start b
Start c
Start d
Stop d
Stop c
Start e
Stop e
Stop b
Stop a
*/
void Run()
{
Tracer() << "ParseRunnableEx\n";
ceda::TraceIndenter indent;
ceda::xstring s = @str
(
{
ParseRunnableEx.X("a")
ParseRunnableEx.X("b")
{
ParseRunnableEx.X("c")
ParseRunnableEx.X("d")
}
ParseRunnableEx.X("e")
}
);
ceda::CSpaceCreator cspace(10); // 10 msec per GC
ceda::ExpressionParser parser;
try
{
parser.Init(s);
// todo: this fails with assertion in DGS, which checks that CSpace has been locked when invoke
// write barrier on indep variables.
//ceda::ParseRunnables(parser);
}
catch(ceda::LexScannerException& e)
{
Tracer() << "Error : " << e << '\n';
}
}
}