- Added still more error checking to PythonCPUPolicy. But the code which calls its methods should be updated to handle the new exceptions...
- Added a base class for cpu policy exceptions to make simpler their catching - Implemented all numeric fields in dialogs with spinboxes, with bounds checking git-svn-id: svn://svn.gna.org/svn/sgpemv2/trunk@838 3ecf2c5c-341e-0410-92b4-d18e462d057c
This commit is contained in:
parent
d3c7b46853
commit
48fc2f5a00
18 changed files with 298 additions and 177 deletions
|
@ -1,4 +1,4 @@
|
|||
import mutex, thread
|
||||
import sys, mutex, thread
|
||||
import sgpem
|
||||
|
||||
## @brief This is an adapter class which acts as a proxy
|
||||
|
@ -26,6 +26,8 @@ class ScriptAdapter :
|
|||
## Var Testable syncronization object
|
||||
_g_mutex = mutex.mutex()
|
||||
|
||||
_g_last_exception = None
|
||||
|
||||
## @brief Constructor of ScriptAdapter
|
||||
#
|
||||
# @param self The caller object
|
||||
|
@ -38,15 +40,19 @@ class ScriptAdapter :
|
|||
#
|
||||
# @param self The caller object
|
||||
def async_configure(self):
|
||||
self._g_mutex.lock(ScriptAdapter._wrap_configure, self )
|
||||
self._g_last_exception = None
|
||||
self._g_mutex.lock(ScriptAdapter._wrap_configure, self )
|
||||
|
||||
def _wrap_configure(self):
|
||||
thread.start_new_thread(ScriptAdapter._wrap_configure_callback, (self,))
|
||||
|
||||
def _wrap_configure_callback(self):
|
||||
# call configure method
|
||||
self._policy.configure()
|
||||
self._g_mutex.unlock()
|
||||
try:
|
||||
self._policy.configure()
|
||||
except:
|
||||
self._g_last_exception = sys.exc_value
|
||||
self._g_mutex.unlock()
|
||||
|
||||
|
||||
## @brief Asynchronously call Policy.sort_queue()
|
||||
|
@ -56,6 +62,7 @@ class ScriptAdapter :
|
|||
#
|
||||
# @param self The caller object
|
||||
def async_sort_queue(self):
|
||||
self._g_last_exception = None
|
||||
self._g_mutex.lock(ScriptAdapter._wrap_sort_queue, self)
|
||||
|
||||
def _wrap_sort_queue(self):
|
||||
|
@ -64,7 +71,11 @@ class ScriptAdapter :
|
|||
def _wrap_sort_queue_callback(self):
|
||||
# here we retrieve and pass the ready queue
|
||||
queue = sgpem.Scheduler.get_instance().get_ready_queue()
|
||||
self._policy.sort_queue(queue)
|
||||
|
||||
try:
|
||||
self._policy.sort_queue(queue)
|
||||
except:
|
||||
self._g_last_exception = sys.exc_value
|
||||
self._g_mutex.unlock()
|
||||
|
||||
|
||||
|
@ -72,26 +83,34 @@ class ScriptAdapter :
|
|||
#
|
||||
# @param self The caller object
|
||||
def async_is_preemptive(self):
|
||||
self._g_last_exception = None
|
||||
self._g_mutex.lock(ScriptAdapter._wrap_is_preemptive, self)
|
||||
|
||||
def _wrap_is_preemptive(self):
|
||||
thread.start_new_thread(ScriptAdapter._wrap_is_preemptive_callback, (self,))
|
||||
|
||||
def _wrap_is_preemptive_callback(self):
|
||||
self._ret_val = self._policy.is_preemptive()
|
||||
try:
|
||||
self._ret_val = self._policy.is_preemptive()
|
||||
except:
|
||||
self._g_last_exception = sys.exc_value
|
||||
self._g_mutex.unlock()
|
||||
|
||||
## @brief Asynchronously call Policy.get_time_slice()
|
||||
#
|
||||
# @param self The caller object
|
||||
def async_get_time_slice(self):
|
||||
self._g_last_exception = None
|
||||
self._g_mutex.lock(ScriptAdapter._wrap_get_time_slice, self)
|
||||
|
||||
def _wrap_get_time_slice(self):
|
||||
thread.start_new_thread(ScriptAdapter._wrap_get_time_slice_callback, (self,))
|
||||
|
||||
def _wrap_get_time_slice_callback(self):
|
||||
self._ret_val = self._policy.get_time_slice()
|
||||
try:
|
||||
self._ret_val = self._policy.get_time_slice()
|
||||
except:
|
||||
self._g_last_exception = sys.exc_value
|
||||
self._g_mutex.unlock()
|
||||
|
||||
## @brief Return the global shared variable with the methods' last return value
|
||||
|
@ -100,3 +119,7 @@ class ScriptAdapter :
|
|||
|
||||
def mutex_test_lock(self):
|
||||
return self._g_mutex.test()
|
||||
|
||||
def get_last_exception(self):
|
||||
return self._g_last_exception
|
||||
|
||||
|
|
|
@ -40,7 +40,7 @@ PythonCPUPolicy::PythonCPUPolicy(const char* name) throw(MalformedPolicyExceptio
|
|||
Py_DECREF(pLoadmeStr);
|
||||
|
||||
if (pUserCPUPolicyModule == NULL)
|
||||
throw MalformedPolicyException(get_exception_information().c_str());
|
||||
throw MalformedPolicyException(get_exception_information());
|
||||
|
||||
// Dictionary with defined ``symbols'' for .pyc file
|
||||
_upolicy_dict = PyModule_GetDict(pUserCPUPolicyModule);
|
||||
|
@ -70,7 +70,7 @@ PythonCPUPolicy::PythonCPUPolicy(const char* name) throw(MalformedPolicyExceptio
|
|||
Py_DECREF(pScriptAdapterModule);
|
||||
|
||||
if (_adapter == NULL)
|
||||
throw MalformedPolicyException(get_exception_information().c_str());
|
||||
throw MalformedPolicyException(get_exception_information());
|
||||
|
||||
// And now, who's your daddy, huh?
|
||||
}
|
||||
|
@ -87,7 +87,7 @@ PythonCPUPolicy::~PythonCPUPolicy()
|
|||
}
|
||||
|
||||
void
|
||||
PythonCPUPolicy::activate()
|
||||
PythonCPUPolicy::activate() throw(UserInterruptException, MalformedPolicyException)
|
||||
{
|
||||
// FIXME write the rest, taking away code from constructor
|
||||
|
||||
|
@ -107,7 +107,7 @@ PythonCPUPolicy::deactivate()
|
|||
|
||||
|
||||
void
|
||||
PythonCPUPolicy::configure() throw(UserInterruptException)
|
||||
PythonCPUPolicy::configure() throw(UserInterruptException, MalformedPolicyException)
|
||||
{
|
||||
PyObject* retval = PyObject_CallMethod(_adapter, "async_configure", NULL);
|
||||
Py_DECREF(retval);
|
||||
|
@ -117,7 +117,7 @@ PythonCPUPolicy::configure() throw(UserInterruptException)
|
|||
|
||||
|
||||
void
|
||||
PythonCPUPolicy::sort_queue() const throw(UserInterruptException)
|
||||
PythonCPUPolicy::sort_queue() const throw(UserInterruptException, MalformedPolicyException)
|
||||
{
|
||||
PyObject* retval = PyObject_CallMethod(_adapter, "async_sort_queue", NULL);
|
||||
|
||||
|
@ -143,7 +143,7 @@ PythonCPUPolicy::get_name() const
|
|||
}
|
||||
|
||||
bool
|
||||
PythonCPUPolicy::is_pre_emptive() const throw(UserInterruptException)
|
||||
PythonCPUPolicy::is_pre_emptive() const throw(UserInterruptException, MalformedPolicyException)
|
||||
{
|
||||
PyObject* retval = PyObject_CallMethod(_adapter, "async_is_preemptive", NULL);
|
||||
Py_DECREF(retval);
|
||||
|
@ -160,7 +160,7 @@ PythonCPUPolicy::is_pre_emptive() const throw(UserInterruptException)
|
|||
|
||||
|
||||
int
|
||||
PythonCPUPolicy::get_time_slice() const throw(UserInterruptException)
|
||||
PythonCPUPolicy::get_time_slice() const throw(UserInterruptException, MalformedPolicyException)
|
||||
{
|
||||
PyObject* retval = PyObject_CallMethod(_adapter, "async_get_time_slice", NULL);
|
||||
|
||||
|
@ -181,7 +181,7 @@ PythonCPUPolicy::get_time_slice() const throw(UserInterruptException)
|
|||
|
||||
|
||||
void
|
||||
PythonCPUPolicy::wait_unlock() const throw(UserInterruptException)
|
||||
PythonCPUPolicy::wait_unlock() const throw(UserInterruptException, MalformedPolicyException)
|
||||
{
|
||||
PyThreadState* _save;
|
||||
int i = 0; // We give the sort_queue() three seconds max time, then...
|
||||
|
@ -198,7 +198,7 @@ PythonCPUPolicy::wait_unlock() const throw(UserInterruptException)
|
|||
assert(retval);
|
||||
still_locked = PyObject_IsTrue(retval);
|
||||
Py_DECREF(retval);
|
||||
|
||||
|
||||
if (i++ > 12) /* waits for WAIT_FOR * 12 microseconds == 3 secs */
|
||||
{
|
||||
PyThreadState_Clear(_save);
|
||||
|
@ -207,13 +207,37 @@ PythonCPUPolicy::wait_unlock() const throw(UserInterruptException)
|
|||
Py_UNBLOCK_THREADS;
|
||||
PyEval_RestoreThread(_save);
|
||||
|
||||
|
||||
if(PyErr_Occurred() != NULL)
|
||||
abort();
|
||||
|
||||
throw UserInterruptException(_("User-defined policy is "
|
||||
"taking too long to terminate."));
|
||||
}
|
||||
}
|
||||
while (still_locked);
|
||||
|
||||
// check if there were unhandled exception in the user-defined code
|
||||
|
||||
PyObject* pException = PyObject_CallMethod(_adapter, "get_last_exception", NULL);
|
||||
|
||||
if(pException != NULL)
|
||||
{
|
||||
if(pException != Py_None)
|
||||
{
|
||||
PyObject* pExceptStr = PyObject_Str(pException);
|
||||
|
||||
string msg = _("unhandled exception in user policy: ");
|
||||
msg += PyString_AsString(pExceptStr);
|
||||
|
||||
Py_DECREF(pExceptStr);
|
||||
Py_DECREF(pException);
|
||||
|
||||
throw MalformedPolicyException(msg);
|
||||
}
|
||||
else
|
||||
Py_DECREF(pException);
|
||||
}
|
||||
|
||||
// What we should really do here:
|
||||
/* do {
|
||||
enable python threads
|
||||
|
@ -260,6 +284,8 @@ PythonCPUPolicy::get_exception_information()
|
|||
if (pValue != NULL) Py_DECREF(pValue);
|
||||
if (pTraceback != NULL) Py_DECREF(pTraceback);
|
||||
|
||||
PyErr_Clear();
|
||||
|
||||
return msg;
|
||||
}
|
||||
|
||||
|
|
|
@ -51,12 +51,12 @@ namespace sgpem
|
|||
/**
|
||||
Calls the method \c async_configure
|
||||
*/
|
||||
void configure() throw(UserInterruptException);
|
||||
void configure() throw(UserInterruptException, MalformedPolicyException);
|
||||
|
||||
/**
|
||||
Calls the method \c async_sort_queue
|
||||
*/
|
||||
void sort_queue() const throw(UserInterruptException);
|
||||
void sort_queue() const throw(UserInterruptException, MalformedPolicyException);
|
||||
|
||||
/**
|
||||
\returns A textual description of this policy.
|
||||
|
@ -69,14 +69,14 @@ namespace sgpem
|
|||
\returns \c TRUE if the policy is preemptive.
|
||||
\returns \c FALSE if the policy is not preemptive.
|
||||
*/
|
||||
bool is_pre_emptive() const throw(UserInterruptException);
|
||||
bool is_pre_emptive() const throw(UserInterruptException, MalformedPolicyException);
|
||||
|
||||
/**
|
||||
\returns The integer value of its time-slice.
|
||||
*/
|
||||
int get_time_slice() const throw(UserInterruptException);
|
||||
int get_time_slice() const throw(UserInterruptException, MalformedPolicyException);
|
||||
|
||||
void activate();
|
||||
void activate() throw(UserInterruptException, MalformedPolicyException);
|
||||
|
||||
void deactivate();
|
||||
|
||||
|
@ -84,7 +84,7 @@ namespace sgpem
|
|||
PythonCPUPolicy(const PythonCPUPolicy&);
|
||||
PythonCPUPolicy& operator=(const PythonCPUPolicy&);
|
||||
|
||||
void wait_unlock() const throw(UserInterruptException);
|
||||
void wait_unlock() const throw(UserInterruptException, MalformedPolicyException);
|
||||
static std::string get_exception_information();
|
||||
|
||||
PyObject* _upolicy_dict;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue