Salome HOME
The final values of InPorts of EndSwitchNodes in a loop may be wrong
[modules/superv.git] / src / GraphExecutor / DataFlowExecutor_PyDynInvoke.cxx
index 22ac4d0be1f10593360f6fe9bc285f7f146b1002..09baea832c157968e828066d9ba003115eb85184 100644 (file)
@@ -15,9 +15,11 @@ using namespace std;
 #include <map>
 
 #include "DataFlowExecutor_InNode.hxx"
+#include "DataFlowExecutor_OutNode.hxx"
 
 using namespace CORBA ;
 
+//static PyObject * MyPyObjSignal = NULL ;
 static PyObject * MyPyObjRef = NULL ;
 static PyObject * MyPyObjIor = NULL ;
 static PyObject * MyPyRunMethod = NULL ;
@@ -33,33 +35,58 @@ bool GraphExecutor::InNode::InitPython() {
   Automaton()->PyLock() ;
 //  PyObject * Module = Py_InitModule( "InitPyRunMethod" , MethodPyRunMethod ) ;
   if ( !Automaton()->PyInitModule() ) {
-    Py_InitModule( "InitPyRunMethod" , MethodPyRunMethod ) ;
+//    Py_InitModule( "InitPyRunMethod" , MethodPyRunMethod ) ;
+    _OutNode->SuperVisionContainer()->ActivatePythonExecution( "InitPyRunMethod" , MethodPyRunMethod ) ;
   }
 //  PyObject * Dictionnary = PyModule_GetDict( Module ) ;
 //  InitPyDynInvokeError = PyErr_NewException( "InitPyDynInvokeError" , NULL , NULL ) ;
 //  PyDict_SetItemString( Dictionnary , InitPyDynInvokeError ) ;
   cdebug << ThreadNo() << "Py_Initialized() " << endl ;
 
+#if 0
+//JR : Python documentation says that there is no sense to set a handler of synchronous
+// signals as SIGSEGV and SIGFPE !!!
+  if ( Automaton()->PyFunction( "PyObjSignal" ) == NULL ) {
+    string aPyFunc ;
+    aPyFunc = "import signal\n" ;
+    aPyFunc += "import InitPyRunMethod\n" ;
+    aPyFunc += "import sys\n" ;
+    aPyFunc += "import CORBA\n" ;
+    aPyFunc += "import omniORB\n" ;
+    aPyFunc += "def PySignalHandler( aSignal , aStackFrame ) :\n" ;
+    aPyFunc += "    print 'PySignalHandler(aSignal =',aSignal,',aStackFrame= ',aStackFrame,')'\n" ;
+    aPyFunc += "InitPyRunMethod.RunMethod( PySignalHandler )\n" ;
+    aPyFunc += "PrevHandler = signal.signal( signal.SIGSEGV , PySignalHandler )\n" ;
+    aPyFunc += "print 'PyObjSignal PrevHandler of SIGSEGV :', PrevHandler\n" ;
+    aPyFunc += "print 'PyObjSignal actual handler of SIGSEGV :', signal.getsignal( signal.SIGSEGV  )\n" ;
+//    if ( PyRun_SimpleString( (char *) aPyFunc.c_str() ) ) {
+    if ( PyRunSimpleString( (char *) aPyFunc.c_str() ) ) {
+      cdebug << ThreadNo() << " " << Name() << " PyRun_SimpleString ERROR " << endl << aPyFunc << endl ;
+      Automaton()->PyUnLock() ;
+      return false ;
+    }
+    MyPyObjSignal = MyPyRunMethod ;
+    Automaton()->PyFunction( "PyObjSignal" , MyPyObjSignal ) ;
+  }
+  else {
+    MyPyObjSignal = Automaton()->PyFunction( "PyObjSignal" ) ;
+  }
+#endif
+
+// PyObjRef convert an IOR (string) to an Python ObjectReference
   if ( Automaton()->PyFunction( "PyObjRef" ) == NULL ) {
     string aPyFunc ;
-//    aPyFunc = "print 'InitPyRunMethod'\n" ;
     aPyFunc = "import InitPyRunMethod\n" ;
-//    aPyFunc += "print 'sys'\n" ;
     aPyFunc += "import sys\n" ;
-//    aPyFunc += "print 'CORBA'\n" ;
     aPyFunc += "import CORBA\n" ;
-//    aPyFunc += "print 'omniORB'\n" ;
     aPyFunc += "import omniORB\n" ;
-//    aPyFunc += "print 'PyObjRef'\n" ;
     aPyFunc += "def PyObjRef( IORObjStr ) :\n" ;
-//    aPyFunc += "    print 'PyObjRef',IORObjStr\n" ;
     aPyFunc += "    orb = CORBA.ORB_init( sys.argv , CORBA.ORB_ID )\n" ;
-//    aPyFunc += "    print 'PyObjRef orb',orb\n" ;
     aPyFunc += "    objref = orb.string_to_object( IORObjStr )\n" ;
-//    aPyFunc += "    print 'PyObjRef IORObjStr objref',IORObjStr,objref\n" ;
     aPyFunc += "    return objref\n" ;
     aPyFunc += "InitPyRunMethod.RunMethod( PyObjRef )\n" ;
-    if ( PyRun_SimpleString( (char *) aPyFunc.c_str() ) ) {
+//    if ( PyRun_SimpleString( (char *) aPyFunc.c_str() ) ) {
+    if ( PyRunSimpleString( (char *) aPyFunc.c_str() ) ) {
       cdebug << ThreadNo() << " " << Name() << " PyRun_SimpleString ERROR " << endl << aPyFunc << endl ;
       Automaton()->PyUnLock() ;
       return false ;
@@ -71,6 +98,7 @@ bool GraphExecutor::InNode::InitPython() {
     MyPyObjRef = Automaton()->PyFunction( "PyObjRef" ) ;
   }
 
+// PyObjRef convert an Python ObjectReference to an IOR (string)
   if ( Automaton()->PyFunction( "PyObjIor" ) == NULL ) {
     string aPyFunc ;
     aPyFunc = "import InitPyRunMethod\n" ;
@@ -78,14 +106,12 @@ bool GraphExecutor::InNode::InitPython() {
     aPyFunc += "import CORBA\n" ;
     aPyFunc += "import omniORB\n" ;
     aPyFunc += "def PyObjIor( ObjRef ) :\n" ;
-//    aPyFunc += "    print 'PyObjIor',ObjRef\n" ;
     aPyFunc += "    orb = CORBA.ORB_init( sys.argv , CORBA.ORB_ID )\n" ;
-//    aPyFunc += "    print 'PyObjIor orb',orb\n" ;
     aPyFunc += "    objIor = orb.object_to_string( ObjRef )\n" ;
-//    aPyFunc += "    print 'PyObjIor ObjRef objIor',ObjRef,objIor\n" ;
     aPyFunc += "    return objIor\n" ;
     aPyFunc += "InitPyRunMethod.RunMethod( PyObjIor )\n" ;
-    if ( PyRun_SimpleString( (char *) aPyFunc.c_str() ) ) {
+//    if ( PyRun_SimpleString( (char *) aPyFunc.c_str() ) ) {
+    if ( PyRunSimpleString( (char *) aPyFunc.c_str() ) ) {
       cdebug << ThreadNo() << " " << Name() << " PyRun_SimpleString ERROR " << endl << aPyFunc << endl ;
       Automaton()->PyUnLock() ;
       return false ;
@@ -103,6 +129,17 @@ bool GraphExecutor::InNode::InitPython() {
   return true ;
 }
 
+void GraphExecutor::InNode::RemovePyDynInvoke( char * PyFuncName ) {
+//  Automaton()->PyLock() ; // Already done ...
+  if ( Automaton()->ErasePyFunction( PyFuncName ) ) {
+    cdebug << "InNode::RemovePyDynInvoke( " << PyFuncName << " ) success" << endl ;
+  }
+  else {
+    cdebug << "InNode::RemovePyDynInvoke( " << PyFuncName << " ) ERROR failed" << endl ;
+  }
+//  Automaton()->PyUnLock() ;
+}
+
 PyObject * GraphExecutor::InNode::InitPyDynInvoke( char * PyFuncName ,
                                                    const SUPERV::ListOfStrings * aPythonFunction ,
                                                    bool & Err ) {
@@ -128,8 +165,10 @@ PyObject * GraphExecutor::InNode::InitPyDynInvoke( char * PyFuncName ,
         aPyFunc += PyFuncName ;
         aPyFunc += " )\n" ;
         /*cdebug *///cout<< "InitPyDynInvoke PyRun_SimpleString " << endl << aPyFunc << endl ;
-        if ( PyRun_SimpleString( (char *) aPyFunc.c_str() ) ) {
-          cdebug << ThreadNo() << " " << Name() << " PyRun_SimpleString ERROR " << endl << aPyFunc << endl ;
+//        if ( PyRun_SimpleString( (char *) aPyFunc.c_str() ) ) {
+        if ( PyRunSimpleString( (char *) aPyFunc.c_str() ) ) {
+          cdebug << ThreadNo() << " " << Name() << " PyRunSimpleString ERROR " << endl << aPyFunc << endl ;
+         PyFuncRunned( false ) ;
           RetVal = false ;
           Err = true ;
         }
@@ -138,7 +177,7 @@ PyObject * GraphExecutor::InNode::InitPyDynInvoke( char * PyFuncName ,
           thePyRunMethod = MyPyRunMethod ;
          
           Automaton()->PyFunction( PyFuncName , thePyRunMethod ) ;
-          cdebug << ThreadNo() << "PyRun_SimpleString( " << (*aPythonFunction)[ 0 ] << " ) " << endl ;
+          cdebug << ThreadNo() << "PyRunSimpleString( " << (*aPythonFunction)[ 0 ] << " ) " << endl ;
         }
       }
       if ( RetVal ) {
@@ -157,7 +196,7 @@ PyObject * GraphExecutor::InNode::InitPyDynInvoke( char * PyFuncName ,
     Automaton()->PyUnLock() ;
   }
 
-  cdebug_out << "InitPyDynInvoke '" << PyFuncName << "' thePyRunMethod Null" << endl ;
+  cdebug_out << "InitPyDynInvoke '" << PyFuncName << "' thePyRunMethod Null Err " << Err << endl ;
   
   return NULL ;
 }
@@ -306,7 +345,8 @@ bool GraphExecutor::InNode::PyDynInvoke( PyObject * MyPyRunMethod ,
         PyTuple_SetItem( MyPyObjRefList , 0 , ObjValue ) ;
         cdebug << "ArgIn" << i << " : " << sname << " " << method << " " << " Value " << IORObjRef << " (objref) "
                << MyPyObjRef->ob_refcnt << "/" << MyPyObjRefList->ob_refcnt << endl ;
-        ResultObj = PyEval_CallObject( MyPyObjRef , MyPyObjRefList ) ;
+//        ResultObj = PyEval_CallObject( MyPyObjRef , MyPyObjRefList ) ;
+        ResultObj = PyEvalCallObject( MyPyObjRef , MyPyObjRefList ) ;
         cdebug << "ObjValue->ob_refcnt" << ObjValue->ob_refcnt << endl ;
         ArgValue = Py_BuildValue( "O" , ResultObj ) ;
         PyTuple_SetItem( ArgsList , i , ArgValue ) ;
@@ -329,7 +369,8 @@ bool GraphExecutor::InNode::PyDynInvoke( PyObject * MyPyRunMethod ,
       }
     }
 
-    Result = PyEval_CallObject( MyPyRunMethod , ArgsList ) ;
+//    Result = PyEval_CallObject( MyPyRunMethod , ArgsList ) ;
+    Result = PyEvalCallObject( MyPyRunMethod , ArgsList ) ;
 
     cdebug << "ArgsList->ob_refcnt" << ArgsList->ob_refcnt << endl ;
 
@@ -501,7 +542,8 @@ bool GraphExecutor::InNode::PyDynInvoke( PyObject * MyPyRunMethod ,
           Py_INCREF( ObjIor ) ;
 //          PyObject_Print( ObjIor , stdout , 0 ) ;
           PyTuple_SetItem( MyPyObjIorList , 0 , ObjIor ) ;
-          ResultIor = PyEval_CallObject( MyPyObjIor , MyPyObjIorList ) ;
+//          ResultIor = PyEval_CallObject( MyPyObjIor , MyPyObjIorList ) ;
+          ResultIor = PyEvalCallObject( MyPyObjIor , MyPyObjIorList ) ;
           cdebug << "ObjIor->ob_refcnt " << ObjIor->ob_refcnt-1 << endl ;
           Py_DECREF( ObjIor ) ;
           cdebug << "MyPyObjIorList->ob_refcnt " << MyPyObjIorList->ob_refcnt-1 << endl ;
@@ -552,3 +594,60 @@ bool GraphExecutor::InNode::PyDynInvoke( PyObject * MyPyRunMethod ,
   return RetVal ;
 
 }
+
+bool GraphExecutor::InNode::PyRunSimpleString( char* thePyString )
+{
+  const bool ErrorValue = true;
+  bool aRet;
+  try {
+    MESSAGE( pthread_self() << "Python method beginning : " << thePyString );
+    cdebug_in << pthread_self() << "Python method beginning : " << thePyString << endl ;
+//    aRet = PyRun_SimpleString( thePyString );
+    aRet = _OutNode->SuperVisionContainer()->ActivatePythonExecution( thePyString ) ;
+    MESSAGE( pthread_self() << "Python method finished." );
+    cdebug_out << pthread_self() << "Python method finished." << endl ;
+  } catch( ... ) {
+    MESSAGE( pthread_self() << "ERROR: Exception caught running Python method." );
+    cdebug_out << pthread_self() << "ERROR: Exception caught running Python method."
+               << endl ;
+    MESSAGE( "       Python was reinitialized.  Previous Python definitions are lost" );
+//    Py_Finalize();
+//    Py_Initialize();
+//    Py_InitModule( "InitPyRunMethod" , MethodPyRunMethod );
+    _OutNode->PyInitialized( false );
+    aRet = ErrorValue;
+  }
+  return aRet;
+}
+
+PyObject * GraphExecutor::InNode::PyEvalCallObject( PyObject * MyPyRunMethod ,
+                                                    PyObject * ArgsList ) {
+  cdebug_in << "Executor::InNode::PyEvalCallObject " << Name() << endl ;
+  PyObject * Result = NULL ;
+  try {
+    MESSAGE( pthread_self() << "PyEval_CallObject method beginning : " );
+    cdebug << pthread_self() << "PyEval_CallObject method beginning : " << Name() << endl ;
+//    Result = PyEval_CallObject( MyPyRunMethod , ArgsList ) ;
+    Result = _OutNode->SuperVisionContainer()->ActivatePythonExecution( MyPyRunMethod , ArgsList ) ;
+    MESSAGE( pthread_self() << "PyEval_CallObject method finished. Result " << Result );
+    cdebug << pthread_self() << "PyEval_CallObject method finished. Result " << Result << endl ;
+    cdebug_out << "Executor::InNode::PyEvalCallObject " << Name() << endl ;
+  } catch( ... ) {
+    MESSAGE( pthread_self() << "ERROR: Exception caught PyEval_CallObject Python method. Result "  << Result );
+    cdebug << pthread_self() << "ERROR: Exception caught PyEval_CallObject Python method. Result "
+           << Result << endl ;
+//    MESSAGE( "       Python was reinitialized.  Previous Python definitions are lost Py_IsInitialized " << Py_IsInitialized() );
+//JR ===> fatal error in python : no current thread
+//    Py_Finalize();
+//    Py_Initialize();
+//    Automaton()->PyInitModule( false ) ;
+//    Py_InitModule( "InitPyRunMethod" , MethodPyRunMethod );
+//    _OutNode->PyInitialized( false );
+    if ( Result == NULL ) {
+      Kill() ; // Reset of _ThreadId
+    }
+    cdebug_out << "Executor::InNode::PyEvalCallObject ERROR catched " << Name()
+               << " Py_IsInitialized " << Py_IsInitialized() << endl ;
+  }
+  return Result ;
+}