summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorStefan Radomski <radomski@tk.informatik.tu-darmstadt.de>2014-08-26 15:11:47 (GMT)
committerStefan Radomski <radomski@tk.informatik.tu-darmstadt.de>2014-08-26 15:11:47 (GMT)
commit0a22a276cfff2155cbaf4939d75c257dfdb46932 (patch)
treeefd057b2bfee89557636819433bc7ecf932153cd /src
parentf3e7f0bb9866edb30682b1e1b72db7c4f6946378 (diff)
downloaduscxml-0a22a276cfff2155cbaf4939d75c257dfdb46932.zip
uscxml-0a22a276cfff2155cbaf4939d75c257dfdb46932.tar.gz
uscxml-0a22a276cfff2155cbaf4939d75c257dfdb46932.tar.bz2
Identify InterpreterIssues at runtime
Diffstat (limited to 'src')
-rw-r--r--src/uscxml/Interpreter.cpp14
-rw-r--r--src/uscxml/Interpreter.h5
-rw-r--r--src/uscxml/debug/InterpreterIssue.cpp35
-rw-r--r--src/uscxml/interpreter/InterpreterRC.cpp5
-rw-r--r--src/uscxml/transform/FlatStateIdentifier.h46
5 files changed, 81 insertions, 24 deletions
diff --git a/src/uscxml/Interpreter.cpp b/src/uscxml/Interpreter.cpp
index b87efed..aa4475c 100644
--- a/src/uscxml/Interpreter.cpp
+++ b/src/uscxml/Interpreter.cpp
@@ -768,6 +768,17 @@ InterpreterState InterpreterImpl::step(int waitForMS) {
microstep(enabledTransitions);
setInterpreterState(USCXML_MICROSTEPPED);
+
+ // check whether we run in cycles
+ FlatStateIdentifier flat(_configuration, _alreadyEntered, _historyValue);
+ if (_microstepConfigurations.find(flat.getStateId()) != _microstepConfigurations.end()) {
+ USCXML_MONITOR_CALLBACK2(reportIssue,
+ InterpreterIssue("Reentering during microstep " + flat.getFlatActive() + " - possible endless loop",
+ Arabica::DOM::Node<std::string>(),
+ InterpreterIssue::USCXML_ISSUE_WARNING));
+ }
+ _microstepConfigurations.insert(flat.getStateId());
+
return _state;
}
_stable = true;
@@ -800,6 +811,7 @@ InterpreterState InterpreterImpl::step(int waitForMS) {
} else {
_stable = true;
+ _microstepConfigurations.clear();
}
if (_state != USCXML_MACROSTEPPED && _state != USCXML_IDLE)
@@ -953,6 +965,8 @@ void InterpreterImpl::stabilize() {
assert(initialTransitions.size() > 0);
enterStates(initialTransitions);
}
+
+ std::set<std::string> configurationsSeen;
do { // process microsteps for enabled transitions until there are no more left
diff --git a/src/uscxml/Interpreter.h b/src/uscxml/Interpreter.h
index 1f62255..7732bfb 100644
--- a/src/uscxml/Interpreter.h
+++ b/src/uscxml/Interpreter.h
@@ -517,7 +517,8 @@ protected:
InterpreterHTTPServlet* _httpServlet;
InterpreterWebSocketServlet* _wsServlet;
std::set<InterpreterMonitor*> _monitors;
-
+ std::set<std::string> _microstepConfigurations;
+
long _lastRunOnMainThread;
std::string _name;
std::string _sessionId;
@@ -836,6 +837,8 @@ public:
virtual void beforeCompletion(Interpreter interpreter) {}
virtual void afterCompletion(Interpreter interpreter) {}
+ virtual void reportIssue(Interpreter interpreter, const InterpreterIssue& issue) {}
+
};
}
diff --git a/src/uscxml/debug/InterpreterIssue.cpp b/src/uscxml/debug/InterpreterIssue.cpp
index 60f8f1b..fedb40f 100644
--- a/src/uscxml/debug/InterpreterIssue.cpp
+++ b/src/uscxml/debug/InterpreterIssue.cpp
@@ -407,7 +407,19 @@ std::list<InterpreterIssue> InterpreterIssue::forInterpreter(InterpreterImpl* in
for (int i = 0; i < invokes.size(); i++) {
Element<std::string> invoke = Element<std::string>(invokes[i]);
if (HAS_ATTR(invoke, "type") && !_factory->hasInvoker(ATTR(invoke, "type"))) {
- issues.push_back(InterpreterIssue("Invoke with unknown type '" + ATTR(invoke, "type") + "'", invoke, InterpreterIssue::USCXML_ISSUE_FATAL));
+ // unknown at factory - adhoc extension?
+ if (HAS_ATTR(invoke, "id") && interpreter->_invokers.find(ATTR(invoke, "id")) != interpreter->_invokers.end())
+ continue; // not an issue
+
+ IssueSeverity severity;
+ if (HAS_ATTR(invoke, "idlocation")) {
+ // we might still resolve at runtime
+ severity = InterpreterIssue::USCXML_ISSUE_WARNING;
+ } else {
+ // fatality!
+ severity = InterpreterIssue::USCXML_ISSUE_FATAL;
+ }
+ issues.push_back(InterpreterIssue("Invoke with unknown type '" + ATTR(invoke, "type") + "'", invoke, severity));
continue;
}
}
@@ -418,6 +430,9 @@ std::list<InterpreterIssue> InterpreterIssue::forInterpreter(InterpreterImpl* in
for (int i = 0; i < sends.size(); i++) {
Element<std::string> send = Element<std::string>(sends[i]);
if (HAS_ATTR(send, "type") && !_factory->hasIOProcessor(ATTR(send, "type"))) {
+ if (interpreter->_ioProcessors.find(ATTR(send, "type")) != interpreter->_ioProcessors.end())
+ continue; // not an issue, available ad-hoc
+
issues.push_back(InterpreterIssue("Send to unknown IO Processor '" + ATTR(send, "type") + "'", send, InterpreterIssue::USCXML_ISSUE_FATAL));
continue;
}
@@ -470,16 +485,18 @@ std::list<InterpreterIssue> InterpreterIssue::forInterpreter(InterpreterImpl* in
}
- // check that the datamodel is known
- if (HAS_ATTR(_scxml, "datamodel")) {
- if (!_factory->hasDataModel(ATTR(_scxml, "datamodel"))) {
- issues.push_back(InterpreterIssue("SCXML document requires unknown datamodel '" + ATTR(_scxml, "datamodel") + "'", _scxml, InterpreterIssue::USCXML_ISSUE_FATAL));
-
- // we cannot even check the rest as we require a datamodel
- return issues;
+ // check that the datamodel is known if not already instantiated
+ if (!interpreter->_dataModel) {
+ if (HAS_ATTR(_scxml, "datamodel")) {
+ if (!_factory->hasDataModel(ATTR(_scxml, "datamodel"))) {
+ issues.push_back(InterpreterIssue("SCXML document requires unknown datamodel '" + ATTR(_scxml, "datamodel") + "'", _scxml, InterpreterIssue::USCXML_ISSUE_FATAL));
+
+ // we cannot even check the rest as we require a datamodel
+ return issues;
+ }
}
}
-
+
bool instantiatedDataModel = false;
// instantiate datamodel if not explicitly set
if (!_dataModel) {
diff --git a/src/uscxml/interpreter/InterpreterRC.cpp b/src/uscxml/interpreter/InterpreterRC.cpp
index d91eadb..4d2b4f6 100644
--- a/src/uscxml/interpreter/InterpreterRC.cpp
+++ b/src/uscxml/interpreter/InterpreterRC.cpp
@@ -33,8 +33,8 @@ namespace uscxml {
using namespace Arabica::XPath;
using namespace Arabica::DOM;
+#ifdef VERBOSE
size_t padding = 0;
-
std::string getPadding() {
std::string pad = "";
for (int i = 0; i < padding; i++) {
@@ -42,7 +42,8 @@ std::string getPadding() {
}
return pad;
}
-
+#endif
+
Arabica::XPath::NodeSet<std::string> InterpreterRC::removeConflictingTransitions(const Arabica::XPath::NodeSet<std::string>& enabledTransitions) {
Arabica::XPath::NodeSet<std::string> filteredTransitions;
diff --git a/src/uscxml/transform/FlatStateIdentifier.h b/src/uscxml/transform/FlatStateIdentifier.h
index 08451c2..0957e34 100644
--- a/src/uscxml/transform/FlatStateIdentifier.h
+++ b/src/uscxml/transform/FlatStateIdentifier.h
@@ -135,57 +135,79 @@ public:
const std::list<std::string>& getActive() {
return active;
}
+ const std::string& getFlatActive() {
+ return flatActive;
+ }
const std::list<std::string>& getVisited() {
return visited;
}
+ const std::string& getFlatVisited() {
+ return flatVisited;
+ }
const std::map<std::string, std::list<std::string> > & getHistory() {
return histories;
}
+ const std::string& getFlatHistory() {
+ return flatHistories;
+ }
protected:
std::list<std::string> active;
std::list<std::string> visited;
std::map<std::string, std::list<std::string> > histories;
+
+ std::string flatActive;
+ std::string flatVisited;
+ std::string flatHistories;
+
std::string stateId;
void initStateId() {
std::stringstream stateIdSS;
-
std::string seperator;
- stateIdSS << "active:{";
+ std::stringstream flatActiveSS;
+ flatActiveSS << "active:{";
for (std::list<std::string>::const_iterator actIter = active.begin(); actIter != active.end(); actIter++) {
- stateIdSS << seperator << *actIter;
+ flatActiveSS << seperator << *actIter;
seperator = ",";
}
- stateIdSS << "}";
+ flatActiveSS << "}";
+ flatActive = flatActiveSS.str();
+ stateIdSS << flatActive;
if (visited.size() > 0) {
+ std::stringstream flatVisitedSS;
seperator = "";
- stateIdSS << ";visited:{";
+ flatVisitedSS << "visited:{";
for (std::list<std::string>::const_iterator visitIter = visited.begin(); visitIter != visited.end(); visitIter++) {
- stateIdSS << seperator << *visitIter;
+ flatVisitedSS << seperator << *visitIter;
seperator = ",";
}
- stateIdSS << "}";
+ flatVisitedSS << "}";
+ flatVisited = flatVisitedSS.str();
+ stateIdSS << ";" << flatVisited;
}
if (histories.size() > 0) {
+ std::stringstream flatHistorySS;
seperator = "";
- stateIdSS << ";history:{";
+ flatHistorySS << "history:{";
for (std::map<std::string, std::list<std::string> >::const_iterator histIter = histories.begin(); histIter != histories.end(); histIter++) {
- stateIdSS << seperator << histIter->first << ":{";
+ flatHistorySS << seperator << histIter->first << ":{";
seperator = ",";
std::string itemSeperator;
for (std::list<std::string>::const_iterator histItemIter = histIter->second.begin(); histItemIter != histIter->second.end(); histItemIter++) {
- stateIdSS << itemSeperator << *histItemIter;
+ flatHistorySS << itemSeperator << *histItemIter;
itemSeperator = ",";
}
- stateIdSS << "}";
+ flatHistorySS << "}";
}
- stateIdSS << "}";
+ flatHistorySS << "}";
+ flatHistories = flatHistorySS.str();
+ stateIdSS << ";" << flatHistories;
}
stateId = stateIdSS.str();