Skip to content

Commit

Permalink
Merge pull request #437 from mo-xiaoming/main
Browse files Browse the repository at this point in the history
add stop function to interrupt compilation
  • Loading branch information
dawa79 authored Mar 23, 2022
2 parents d973b45 + bb19e92 commit 84054ef
Show file tree
Hide file tree
Showing 3 changed files with 21 additions and 10 deletions.
6 changes: 5 additions & 1 deletion include/hobbes/eval/cmodule.H
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
#include <hobbes/eval/func.H>
#include <hobbes/lang/module.H>

#include <functional>

namespace hobbes {

class cc;
Expand All @@ -17,7 +19,9 @@ void pushModuleDir(const std::string&);
void popModuleDir();

// compile a whole module into a cc context
void compile(cc*, const ModulePtr& m);
// once stopFn() is true, the compilation stops prematurely,
// cc is not valid anymore, all you can do is to destroy it
void compile(cc*, const ModulePtr& m, std::function<bool()> stopFn=[] { return false; });

// set language options, display language options
using OptDescs = std::map<std::string, std::string>;
Expand Down
14 changes: 13 additions & 1 deletion lib/hobbes/eval/cmodule.C
Original file line number Diff line number Diff line change
Expand Up @@ -794,8 +794,11 @@ void compile(const ModulePtr &, cc *, const MSafePragmaDef *mpd) {
// for now, just treat each definition independently and stick it in the input
// environment
// (this disallows things like mutual recursion)
void compile(cc *e, const ModulePtr &m) {
void compile(cc *e, const ModulePtr &m, std::function<bool()> stopFn) {
for (const auto& tmd : m->definitions()) {
if (stopFn()) {
return;
}
auto md = applyTypeDefns(m, e, tmd);

if (const MImport *imp = is<MImport>(md)) {
Expand All @@ -821,20 +824,29 @@ void compile(cc *e, const ModulePtr &m) {

// compile unsafe pragma
for (const auto& tmd : m->definitions()) {
if (stopFn()) {
return;
}
if (const MUnsafePragmaDef *vpd = is<MUnsafePragmaDef>(tmd)) {
compile(m, e, vpd);
}
}

// compile safe pragma
for (const auto& tmd : m->definitions()) {
if (stopFn()) {
return;
}
if (const MSafePragmaDef *vpd = is<MSafePragmaDef>(tmd)) {
compile(m, e, vpd);
}
}

// generate unsafe transitive closure
for (const auto& tmd : m->definitions()) {
if (stopFn()) {
return;
}
if (const MVarDef *vd = is<MVarDef>(tmd)) {
switchOf(vd->varExpr(), buildTransitiveUnsafePragmaClosure(*vd));
}
Expand Down
11 changes: 3 additions & 8 deletions test/Spawn.C
Original file line number Diff line number Diff line change
Expand Up @@ -27,11 +27,6 @@ void startChild(int t, hobbes::proc &p) {
});
}

bool hasProcessExited(pid_t pid) {
const std::string procDir = "/proc/" + std::to_string(pid);
return !exists(procDir);
}

bool msgInException(const std::exception &e, const std::string &msg) {
return std::string(e.what()).find(msg) != std::string::npos;
}
Expand All @@ -40,7 +35,7 @@ const char *const KEY = "HOBBES_LOADING_TIMEOUT_IN_SECS";
} // namespace

TEST(Spawn, TimeoutKill) {
hobbes::proc p;
hobbes::proc p{};
hobbes::str::env(KEY, "1"); // this may affect other tests' behavior
bool exp = false;
try {
Expand All @@ -50,11 +45,11 @@ TEST(Spawn, TimeoutKill) {
EXPECT_TRUE(msgInException(e, "timed out"));
}
EXPECT_TRUE(exp);
EXPECT_TRUE(hasProcessExited(p.pid));
//p is invalid when spawn goes wrong, cannot be checked against
}

TEST(Spawn, Normal) {
hobbes::proc p;
hobbes::proc p{};
unsetenv(KEY);
startChild(2, p); // should not throw any exceptions
}

0 comments on commit 84054ef

Please sign in to comment.