diff --git a/Makefile.am b/Makefile.am index 5a94c10..518795b 100644 --- a/Makefile.am +++ b/Makefile.am @@ -358,6 +358,7 @@ src_testsuite_test_history_SOURCES = \ src_testsuite_test_python_loader_CPPFLAGS = \ -I@top_srcdir@/src \ + -DMODDIR="\"$(pyloaderdir)\"" \ $(PYTHON_CPPFLAGS) \ $(GLIBMM_CFLAGS) \ $(GTHREAD_CFLAGS) @@ -365,10 +366,14 @@ src_testsuite_test_python_loader_DEPENDENCIES = \ src/backend/pyloader/libpyloader.la src_testsuite_test_python_loader_LDFLAGS = \ src/backend/libbackend.la \ - src/backend/pyloader/libpyloader.la \ - $(GLIBMM_LIBS) $(GTHREAD_LIBS) + $(GLIBMM_LIBS) $(GTHREAD_LIBS) \ + $(PYTHON_LDFLAGS) \ + $(PYTHON_EXTRA_LIBS) \ + $(PYTHON_EXTRA_LDFLAGS) src_testsuite_test_python_loader_SOURCES = \ src/testsuite/test-python_loader.cc \ + src/backend/pyloader/python_policy.cc \ + src/backend/pyloader/python_policy_manager.cc \ src/standard_io.cc \ src/text_simulation.cc \ src/observer.cc \ diff --git a/src/backend/observed_subject.hh b/src/backend/observed_subject.hh index 8025ddf..1693d3a 100644 --- a/src/backend/observed_subject.hh +++ b/src/backend/observed_subject.hh @@ -41,7 +41,7 @@ namespace sgpem class SG_DLLEXPORT ObservedSubject { public: - virtual ~ObservedSubject() =0; + virtual ~ObservedSubject() = 0; /** This method calls Update() on each attached Observer. It should be called when the internal state diff --git a/src/backend/pyloader/python_policy.cc b/src/backend/pyloader/python_policy.cc index 5199159..92c30b7 100644 --- a/src/backend/pyloader/python_policy.cc +++ b/src/backend/pyloader/python_policy.cc @@ -173,6 +173,12 @@ PythonPolicy::wait_unlock() const throw(UserInterruptException) if(i++ > 120) { + + PyThreadState_Clear(_save); + PyEval_RestoreThread(_save); + + //Py_UNBLOCK_THREADS; + throw UserInterruptException("User-defined policy is " "taking too long to terminate."); } diff --git a/src/backend/scheduler.cc b/src/backend/scheduler.cc index 71c03ee..6471ff4 100644 --- a/src/backend/scheduler.cc +++ b/src/backend/scheduler.cc @@ -80,7 +80,7 @@ Scheduler::get_policy() void -Scheduler::step_forward() +Scheduler::step_forward() throw(UserInterruptException) { try { @@ -196,11 +196,13 @@ Scheduler::step_forward() } catch( UserInterruptException e ) { - // FIXME : Naive. - cerr << "Exception: " << e.what() << endl; - - // Errrrr.... you won't like this: _policy_manager.init(); + + throw; + + //TODO Do we need to perform some cleanup operation here? + // Do we need to update something? + // https://sourceforge.net/tracker/?func=detail&atid=105470&aid=1165761&group_id=5470 // maybe it's that??? oh, damn. // or maybe not. see http://www.python.org/doc/2.4.2/api/initialization.html @@ -210,3 +212,4 @@ Scheduler::step_forward() // - SimulationController that everything stopped } } + diff --git a/src/backend/scheduler.hh b/src/backend/scheduler.hh index 13267c4..58a99b4 100644 --- a/src/backend/scheduler.hh +++ b/src/backend/scheduler.hh @@ -35,6 +35,7 @@ namespace sgpem #include "observed_subject.hh" #include "history.hh" #include "schedulable_list.hh" +#include "user_interrupt_exception.hh" namespace sgpem { @@ -96,7 +97,7 @@ namespace sgpem at the simulation instant next to the current one, and extends the History by one instant with it. */ - void step_forward(); + void step_forward() throw(UserInterruptException); /** Sets the policy that will be used to generate the simulation at the next instant. \param policy the policy that will be used to generate the simulation at the next instant. diff --git a/src/simulation.cc b/src/simulation.cc index 8a976d4..71f905b 100644 --- a/src/simulation.cc +++ b/src/simulation.cc @@ -73,7 +73,7 @@ Simulation::reset() } void -Simulation::run() +Simulation::run() throw(UserInterruptException) { History& h = History::get_instance(); @@ -105,12 +105,22 @@ loop: return; } - //step forward - Scheduler::get_instance().step_forward(); + try + { + //step forward + Scheduler::get_instance().step_forward(); - //sleep - Glib::usleep(_timer_interval*1000); + //sleep + Glib::usleep(_timer_interval*1000); + } + catch(UserInterruptException e) + { + stop(); + + throw; + } + //check the state if (_state == state_stopped || _state == state_paused) return; @@ -136,24 +146,43 @@ loop: //by the last execution of upadate() _state = state_paused; else - //step forward - Scheduler::get_instance().step_forward(); + { + + try + { + //step forward + Scheduler::get_instance().step_forward(); + } + catch(UserInterruptException e) + { + throw; + } + } } } void -Simulation::jump_to(const uint& where) +Simulation::jump_to(const uint& where) throw(UserInterruptException) { //jump to position 0 reset(); bool old = _mode; _mode = false; - // executes "where" steps - for (uint i=0; i < where; i++) - run(); + + try + { + // executes "where" steps + for (uint i=0; i < where; i++) + run(); + } + catch(UserInterruptException e) + { + _mode = old; + throw; + } _state = state_paused; _mode = old; diff --git a/src/simulation.hh b/src/simulation.hh index e2fe794..b2d4adf 100644 --- a/src/simulation.hh +++ b/src/simulation.hh @@ -72,7 +72,7 @@ namespace sgpem Advances the simulation by one or more steps, depending on the actual state and on the value set with set_mode(). */ - void run(); + void run() throw(UserInterruptException); /** \brief Pauses a running simulation. @@ -103,7 +103,7 @@ namespace sgpem /** \brief Causes the simulation to jump to the given time unit. */ - void jump_to(const uint&); + void jump_to(const uint&) throw(UserInterruptException); /** \brief Setter for the attribute timer_interval. diff --git a/src/testsuite/python_loader_configure.py b/src/testsuite/python_loader_configure.py index b15ca09..0af04bc 100644 --- a/src/testsuite/python_loader_configure.py +++ b/src/testsuite/python_loader_configure.py @@ -6,6 +6,7 @@ class python_loader_configure(Policy) : pass; def configure(self): + print "[II] Entering willingly an endless loop." while True: pass diff --git a/src/testsuite/python_loader_get_time_slice.py b/src/testsuite/python_loader_get_time_slice.py index 37e1cea..e1764e4 100644 --- a/src/testsuite/python_loader_get_time_slice.py +++ b/src/testsuite/python_loader_get_time_slice.py @@ -12,6 +12,7 @@ class python_loader_get_time_slice(Policy) : return False def get_time_slice(self): + print "[II] Entering willingly an endless loop." while True: pass return -1 diff --git a/src/testsuite/python_loader_is_preemptive.py b/src/testsuite/python_loader_is_preemptive.py index 01f6fc3..fa89f3c 100644 --- a/src/testsuite/python_loader_is_preemptive.py +++ b/src/testsuite/python_loader_is_preemptive.py @@ -9,6 +9,7 @@ class python_loader_is_preemptive(Policy) : pass def is_preemptive(self): + print "[II] Entering willingly an endless loop." while True: pass return False diff --git a/src/testsuite/python_loader_sort_queue.py b/src/testsuite/python_loader_sort_queue.py index 5accd57..01c3a3a 100644 --- a/src/testsuite/python_loader_sort_queue.py +++ b/src/testsuite/python_loader_sort_queue.py @@ -15,5 +15,6 @@ class python_loader_sort_queue(Policy) : return -1 def sort_queue(self, event, queue): + print "[II] Entering willingly an endless loop." while True: pass diff --git a/src/testsuite/test-python_loader.cc b/src/testsuite/test-python_loader.cc index e65a83d..40367cd 100644 --- a/src/testsuite/test-python_loader.cc +++ b/src/testsuite/test-python_loader.cc @@ -62,7 +62,7 @@ main(int argc, char** argv) { exit(-1); } else - // Add current directory to search for uninstalled policies + // Add argv[1] as the directory to search for uninstalled policies sgpem::GlobalSettings::instance().add_policies_dir(argv[1]); Glib::thread_init(); @@ -94,15 +94,19 @@ main(int argc, char** argv) { polman.test_init("python_loader_configure"); text_sim.run(); + text_sim.stop(); polman.test_init("python_loader_is_preemptive"); text_sim.run(); + text_sim.stop(); polman.test_init("python_loader_get_time_slice"); text_sim.run(); + text_sim.stop(); polman.test_init("python_loader_sort_queue"); text_sim.run(); + text_sim.stop(); exit(0); } diff --git a/src/text_simulation.cc b/src/text_simulation.cc index bfa7978..64d4b7f 100644 --- a/src/text_simulation.cc +++ b/src/text_simulation.cc @@ -110,7 +110,18 @@ check: "by its priority enclosed between round parenthesis.")); return; } - obj->run(); + + try + { + obj->run(); + } + catch(UserInterruptException e) + { + obj->_devices[quale]->write_buffer(_("\nERROR: ")); + obj->_devices[quale]->write_buffer(_(e.what())); + obj->_devices[quale]->write_buffer(_("\nSimulation is now stopped")); + + } } else if (arguments[param] == "PAUSE") {