From 5c98a5d6e7ff4f63723638c5ffd29844d5c689ec Mon Sep 17 00:00:00 2001 From: Jason Turner Date: Tue, 9 Mar 2010 02:09:05 +0000 Subject: [PATCH] Add sync_cache to set_state code to fix logic flaw in resetting of state and memory leak. #92 --- .../chaiscript/dispatchkit/dispatchkit.hpp | 13 ++- src/memory_leak_test.cpp | 83 +++++++++++++++++++ 2 files changed, 92 insertions(+), 4 deletions(-) create mode 100644 src/memory_leak_test.cpp diff --git a/include/chaiscript/dispatchkit/dispatchkit.hpp b/include/chaiscript/dispatchkit/dispatchkit.hpp index 1cc3346..5daa4c4 100644 --- a/include/chaiscript/dispatchkit/dispatchkit.hpp +++ b/include/chaiscript/dispatchkit/dispatchkit.hpp @@ -342,13 +342,10 @@ namespace chaiscript void sync_cache() { - m_stack_holder->stack->get<0>().clear(); - #ifndef CHAISCRIPT_NO_THREADS boost::shared_lock l(m_mutex); #endif - - get_function_cache() = m_state.m_functions; + sync_cache_no_lock(); } /** @@ -670,6 +667,7 @@ namespace chaiscript #endif m_state = t_state; + sync_cache_no_lock(); } @@ -688,6 +686,13 @@ namespace chaiscript return m_stack_holder->function_cache; } + void sync_cache_no_lock() + { + m_stack_holder->stack->get<0>().clear(); + + get_function_cache() = m_state.m_functions; + } + /** * Throw a reserved_word exception if the name is not allowed diff --git a/src/memory_leak_test.cpp b/src/memory_leak_test.cpp new file mode 100644 index 0000000..571d9fe --- /dev/null +++ b/src/memory_leak_test.cpp @@ -0,0 +1,83 @@ +#include + +#include "chaiscript/chaiscript.hpp" + +using namespace chaiscript; + +std::string get_next_command() { +#ifdef READLINE_AVAILABLE + char *input_raw; + input_raw = readline("eval> "); + add_history(input_raw); + return std::string(input_raw); +#else + std::string retval; + std::cout << "eval> "; + std::getline(std::cin, retval); + return retval; +#endif +} + +void fuction(void) +{ + // do nothing +} + +class test +{ + ChaiScript chai; + ChaiScript::State backupState; +public: + test() + { + backupState = chai.get_state(); + } + ~test(){} + + void ResetState() + { + chai.set_state(backupState); + chai.add(fun(&fuction),"Whatever()"); + } + void RunFile(std::string sFile) + { + chaiscript::Boxed_Value val; + try { + chaiscript::Boxed_Value val = chai.eval_file(sFile); + } + catch (std::exception &e) { + std::cout << e.what() << std::endl; + } + } + +}; + + + +int main(int argc, char *argv[]) { + + test myChai; + + + std::string command = ""; + + // + // this loop increases memoryusage, if RunFile is not called (just hittin enter) + // as soon RunFile gets called, memory will be freed. + // + // scenario1 - RunFile gets called every Loop: memoryusage does not change + // scenario2 - RunFile gets never called (just hitting enter): memoryusage increases every loop + // scenario3 - RunFile gets in changing intervals: memoryusage goes up and down, but never as + // low as in case 1 scenario3 : + + while(command != "quit") + { + for(int i = 1; i < 200; i++) + myChai.ResetState(); + + if(command == "runfile") + myChai.RunFile("Test.chai"); + + command = get_next_command(); + } +}