aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorPetteri Räty <petsku@petteriraty.eu>2011-05-18 10:24:09 +0300
committerPetteri Räty <petsku@petteriraty.eu>2011-05-18 15:43:01 +0300
commit1db4915f98c4a6943aa685840a2353c029ec3309 (patch)
tree61d378ee06b8ab9171d6bb1ac983114f41f2a69d /src
parentBuiltins: support null command (diff)
downloadlibbash-1db4915f98c4a6943aa685840a2353c029ec3309.tar.gz
libbash-1db4915f98c4a6943aa685840a2353c029ec3309.tar.bz2
libbash-1db4915f98c4a6943aa685840a2353c029ec3309.zip
multithread
Diffstat (limited to 'src')
-rw-r--r--src/builtins/source_builtin.cpp43
-rw-r--r--src/core/bash_ast.cpp35
-rw-r--r--src/core/bash_ast.h1
3 files changed, 59 insertions, 20 deletions
diff --git a/src/builtins/source_builtin.cpp b/src/builtins/source_builtin.cpp
index 383b716..ee95e29 100644
--- a/src/builtins/source_builtin.cpp
+++ b/src/builtins/source_builtin.cpp
@@ -28,6 +28,7 @@
#include <iostream>
#include <string>
#include <unordered_map>
+#include <thread>
#include "builtins/builtin_exceptions.h"
#include "cppbash_builtin.h"
@@ -35,6 +36,31 @@
#include "core/interpreter_exception.h"
#include "core/bash_ast.h"
+namespace {
+ std::mutex parse_mutex;
+
+ std::shared_ptr<bash_ast>& parse(const std::string& path)
+ {
+ static std::unordered_map<std::string, std::shared_ptr<bash_ast>> ast_cache;
+
+ std::lock_guard<std::mutex> parse_lock(parse_mutex);
+
+ auto& stored_ast = ast_cache[path];
+ if(!stored_ast)
+ {
+ std::ifstream input(path);
+ if(!input)
+ throw interpreter_exception(path + " can't be read");
+
+ stored_ast.reset(new bash_ast(input));
+ if(stored_ast->get_error_count())
+ std::cerr << path << " could not be parsed properly" << std::endl;
+ }
+
+ return stored_ast;
+ }
+}
+
int source_builtin::exec(const std::vector<std::string>& bash_args)
{
static std::unordered_map<std::string, std::shared_ptr<bash_ast>> ast_cache;
@@ -42,24 +68,9 @@ int source_builtin::exec(const std::vector<std::string>& bash_args)
if(bash_args.size() == 0)
throw interpreter_exception("should provide one argument for source builtin");
- // we need fix this to pass extra arguments as positional parameters
- const std::string& path = bash_args[0];
-
- auto& stored_ast = ast_cache[path];
- if(!stored_ast)
- {
- std::ifstream input(path);
- if(!input)
- throw interpreter_exception(path + " can't be read");
-
- stored_ast.reset(new bash_ast(input));
- if(stored_ast->get_error_count())
- std::cerr << path << " could not be parsed properly" << std::endl;
- }
-
try
{
- stored_ast->interpret_with(_walker);
+ parse(bash_args.front())->interpret_with(_walker);
}
catch(return_exception& e) {}
diff --git a/src/core/bash_ast.cpp b/src/core/bash_ast.cpp
index 0bf8938..2f729a4 100644
--- a/src/core/bash_ast.cpp
+++ b/src/core/bash_ast.cpp
@@ -25,6 +25,7 @@
#include "core/bash_ast.h"
#include <sstream>
+#include <thread>
#include "core/interpreter_exception.h"
#include "core/interpreter.h"
@@ -49,9 +50,30 @@ bash_ast::bash_ast(std::istream& source): error_count(0)
init_parser();
}
+namespace
+{
+ std::mutex string_mutex;
+
+ pANTLR3_STRING locked_newRaw8(pANTLR3_STRING_FACTORY factory)
+ {
+ std::lock_guard<std::mutex> l(string_mutex);
+ pANTLR3_STRING_FACTORY pristine = antlr3StringFactoryNew();
+ pANTLR3_STRING result = pristine->newRaw(factory);
+ pristine->close(pristine);
+ return result;
+ }
+
+ void locked_destroy(pANTLR3_STRING_FACTORY factory, pANTLR3_STRING string)
+ {
+ std::lock_guard<std::mutex> l(string_mutex);
+ pANTLR3_STRING_FACTORY pristine = antlr3StringFactoryNew();
+ pristine->destroy(factory, string);
+ pristine->close(pristine);
+ }
+}
+
bash_ast::~bash_ast()
{
- nodes->free(nodes);
psr->free(psr);
tstream->free(tstream);
lxr->free(lxr);
@@ -86,22 +108,29 @@ void bash_ast::init_parser()
}
langAST.reset(new libbashParser_start_return(psr->start(psr)));
+ langAST->tree->strFactory->newRaw = &locked_newRaw8;
+ langAST->tree->strFactory->destroy = &locked_destroy;
error_count = psr->pParser->rec->getNumberOfSyntaxErrors(psr->pParser->rec);
- nodes = antlr3CommonTreeNodeStreamNewTree(langAST->tree, ANTLR3_SIZE_HINT);
}
void bash_ast::interpret_with(interpreter& walker)
{
set_interpreter(&walker);
+
+ auto nodes = antlr3CommonTreeNodeStreamNewTree(langAST->tree, ANTLR3_SIZE_HINT);
plibbashWalker treePsr = libbashWalkerNew(nodes);
treePsr->start(treePsr);
treePsr->free(treePsr);
+ nodes->free(nodes);
}
std::string bash_ast::get_dot_graph()
{
+ auto nodes = antlr3CommonTreeNodeStreamNewTree(langAST->tree, ANTLR3_SIZE_HINT);
pANTLR3_STRING graph = nodes->adaptor->makeDot(nodes->adaptor, langAST->tree);
- return std::string(reinterpret_cast<char*>(graph->chars));
+ std::string result(reinterpret_cast<char*>(graph->chars));
+ nodes->free(nodes);
+ return result;
}
std::string bash_ast::get_string_tree()
diff --git a/src/core/bash_ast.h b/src/core/bash_ast.h
index e587d81..852899c 100644
--- a/src/core/bash_ast.h
+++ b/src/core/bash_ast.h
@@ -47,7 +47,6 @@ class bash_ast
pANTLR3_COMMON_TOKEN_STREAM tstream;
libbashParser_Ctx_struct* psr;
std::unique_ptr<libbashParser_start_return_struct> langAST;
- pANTLR3_COMMON_TREE_NODE_STREAM nodes;
int error_count;
void init_parser();