memory leak fix in case of erroneous python code is sent to the server
authorFilippo Gioachin <gioachin@illinois.edu>
Wed, 6 Oct 2004 22:48:17 +0000 (22:48 +0000)
committerFilippo Gioachin <gioachin@illinois.edu>
Wed, 6 Oct 2004 22:48:17 +0000 (22:48 +0000)
src/libs/ck-libs/pythonCCS/PythonCCS.C
src/libs/ck-libs/pythonCCS/PythonCCS.h

index db30c30fcb202ab1e5d505576b0b5a50ab869cef..9323af1041b071198941982d3bd8299abe1540c6 100644 (file)
@@ -176,12 +176,26 @@ void PythonObject::iterate (CkCcsRequestMsg *msg) {
   struct _node* programNode = PyParser_SimpleParseString(userCode, Py_file_input);
   if (programNode==NULL) {
     CkPrintf("Program error\n");
+    // distroy map element in pyWorkers and terminate interpreter
+    Py_EndInterpreter(pts);
+    PyEval_ReleaseLock();
+    CmiLock(CsvAccess(pyLock));
+    CsvAccess(pyWorkers)->erase(pyReference);
+    CmiUnlock(CsvAccess(pyLock));
+    delete msg;
     return;
   }
   PyCodeObject *program = PyNode_Compile(programNode, "");
   if (program==NULL) {
     CkPrintf("Program error\n");
     PyNode_Free(programNode);
+    // distroy map element in pyWorkers and terminate interpreter
+    Py_EndInterpreter(pts);
+    PyEval_ReleaseLock();
+    CmiLock(CsvAccess(pyLock));
+    CsvAccess(pyWorkers)->erase(pyReference);
+    CmiUnlock(CsvAccess(pyLock));
+    delete msg;
     return;
   }
   PyObject *code = PyEval_EvalCode(program, dict, dict);
@@ -189,6 +203,13 @@ void PythonObject::iterate (CkCcsRequestMsg *msg) {
     CkPrintf("Program error\n");
     PyNode_Free(programNode);
     Py_DECREF(program);
+    // distroy map element in pyWorkers and terminate interpreter
+    Py_EndInterpreter(pts);
+    PyEval_ReleaseLock();
+    CmiLock(CsvAccess(pyLock));
+    CsvAccess(pyWorkers)->erase(pyReference);
+    CmiUnlock(CsvAccess(pyLock));
+    delete msg;
     return;
   }
 
@@ -200,6 +221,13 @@ void PythonObject::iterate (CkCcsRequestMsg *msg) {
     PyNode_Free(programNode);
     Py_DECREF(program);
     Py_DECREF(code);
+    // distroy map element in pyWorkers and terminate interpreter
+    Py_EndInterpreter(pts);
+    PyEval_ReleaseLock();
+    CmiLock(CsvAccess(pyLock));
+    CsvAccess(pyWorkers)->erase(pyReference);
+    CmiUnlock(CsvAccess(pyLock));
+    delete msg;
     return;
   }
 
@@ -217,6 +245,10 @@ void PythonObject::iterate (CkCcsRequestMsg *msg) {
   PyObject *result;
   while (more) {
     result = PyObject_CallObject(item, arg);
+    if (!result) {
+      CkPrintf("Python Call error\n");
+      break;
+    }
     more = nextIteratorUpdate(part, result, userIterator);
     Py_DECREF(result);
   }
index 4c22b06d2bc95af13dc1b0fbe0271d0e9f2467e9..ee09d437853db15a3b3f0907a101f239339b985f 100644 (file)
@@ -70,14 +70,14 @@ class PythonObject {
   // methods for accessing charm varibles from inside python
   // read: input an object which describes where the data should be read from, return a PyObject with the given data
   // write: input two object describing where the data should be written, and the actual data
-  virtual PyObject* read(PyObject* where) {CkAbort("PythonCCS: Method read should be reimplemented");};
+  virtual PyObject* read(PyObject* where) {CkAbort("PythonCCS: Method read should be reimplemented"); return NULL; };
   virtual void write(PyObject* where, PyObject* what) {CkAbort("PythonCCS: Method write should be reimplemented");};
 
   // methods to create iterators for iterative python invocations
   // buildIterator: input a PyObject, which is an empty class to be filled with data, and a void pointer describing over what to iterate (user defined format). Should return 1, if it returns 0 no computation is done
   // nextIteratorUpdate: input a PyObject to be filled with the next iterator, this contains the previous iterator, so if the python code modified the object, here the new information can be found. A Python object with the result returned by the python code, and the description of the iterator (as in buildIterator). Return 1 if there is a new object, 0 if there are no more objects in the iterator.
-  virtual int buildIterator(PyObject*, void*) {CkAbort("PythonCCS: Method buildIterator should be reimplemented");};
-  virtual int nextIteratorUpdate(PyObject*, PyObject*, void*) {CkAbort("PythonCCS: Method nextIteratorUpdate should be reimplemented");};
+  virtual int buildIterator(PyObject*, void*) {CkAbort("PythonCCS: Method buildIterator should be reimplemented"); return 0; };
+  virtual int nextIteratorUpdate(PyObject*, PyObject*, void*) {CkAbort("PythonCCS: Method nextIteratorUpdate should be reimplemented"); return 0; };
 
 };