Salome HOME
0023366: [CEA 1972] Porting Salome to GCC 6
[modules/kernel.git] / src / Container / Container_i.cxx
index 8d9a382eb9ce5ffc5bde13676e9f8059136719c5..68373b289881b5a0bda0e0992352d05987b99b5a 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2013  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2016  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
@@ -6,7 +6,7 @@
 // This library is free software; you can redistribute it and/or
 // modify it under the terms of the GNU Lesser General Public
 // License as published by the Free Software Foundation; either
-// version 2.1 of the License.
+// version 2.1 of the License, or (at your option) any later version.
 //
 // This library is distributed in the hope that it will be useful,
 // but WITHOUT ANY WARRANTY; without even the implied warranty of
@@ -201,15 +201,20 @@ Engines_Container_i::Engines_Container_i (CORBA::ORB_ptr orb,
     myCommand += "')\n";
     SCRUTE(myCommand);
 
-    // [ABN]: using the PyGILState* API here is unstable. omniORB logic is invoked
-    // by the Python code executed below, and in some (random) cases, the Python code
-    // execution ends with a PyThreadState which was not the one we have here.
-    // (TODO: understand why ...)
-    // To be on the safe side we get and load the thread state ourselves:
-    //PyGILState_STATE gstate = PyGILState_Ensure();
-    PyEval_AcquireLock();  // get GIL
-    PyThreadState * mainThreadState = PyThreadState_Get();
-    PyThreadState_Swap(mainThreadState);
+    //[RNV]: Comment the PyEval_AcquireLock() and PyEval_ReleaseLock() because this 
+    //approach leads to the deadlock of the main thread of the application on Windows platform
+    //in case if cppContainer runs in the standalone mode. The problem with the PyThreadState 
+    //described by ABN seems not reproduced, to be checked carefully later...
+    PyGILState_STATE gstate = PyGILState_Ensure();
+    
+    //// [ABN]: using the PyGILState* API here is unstable. omniORB logic is invoked
+    //// by the Python code executed below, and in some (random) cases, the Python code
+    //// execution ends with a PyThreadState which was not the one we have here.
+    //// (TODO: understand why ...)
+    //// To be on the safe side we get and load the thread state ourselves:    
+    //PyEval_AcquireLock();  // get GIL
+    //PyThreadState * mainThreadState = PyThreadState_Get();
+    //PyThreadState_Swap(mainThreadState);
 
 #ifdef WIN32
     // mpv: this is temporary solution: there is a unregular crash if not
@@ -225,9 +230,9 @@ Engines_Container_i::Engines_Container_i (CORBA::ORB_ptr orb,
     PyObject *globals = PyModule_GetDict(mainmod);
     _pyCont = PyDict_GetItemString(globals, "pyCont");
 
-    PyThreadState_Swap(NULL);
-    PyEval_ReleaseLock();
-    //PyGILState_Release(gstate);
+    //PyThreadState_Swap(NULL);
+    //PyEval_ReleaseLock();
+    PyGILState_Release(gstate);
 
     fileTransfer_i* aFileTransfer = new fileTransfer_i();
     CORBA::Object_var obref=aFileTransfer->_this();
@@ -249,6 +254,18 @@ Engines_Container_i::~Engines_Container_i()
     delete _id;
   if(_NS)
     delete _NS;
+  for(std::map<std::string,Engines::PyNode_var>::iterator it=_dftPyNode.begin();it!=_dftPyNode.end();it++)
+    {
+      Engines::PyNode_var tmpVar((*it).second);
+      if(!CORBA::is_nil(tmpVar))
+        tmpVar->UnRegister();
+    }
+  for(std::map<std::string,Engines::PyScriptNode_var>::iterator it=_dftPyScriptNode.begin();it!=_dftPyScriptNode.end();it++)
+    {
+      Engines::PyScriptNode_var tmpVar((*it).second);
+      if(!CORBA::is_nil(tmpVar))
+        tmpVar->UnRegister();
+    }
 }
 
 //=============================================================================
@@ -949,6 +966,41 @@ Engines_Container_i::createPythonInstance(std::string CompName, int studyId,
   return iobject._retn();
 }
 
+char *
+Engines_Container_i::create_python_service_instance(const char * CompName,
+                                                    CORBA::String_out reason)
+{
+  CORBA::Object_var object = CORBA::Object::_nil();
+
+  _numInstanceMutex.lock() ; // lock on the instance number
+  _numInstance++ ;
+  int numInstance = _numInstance ;
+  _numInstanceMutex.unlock() ;
+
+  char aNumI[12];
+  sprintf( aNumI , "%d" , numInstance ) ;
+  std::string instanceName = std::string(CompName) + "_inst_" + aNumI ;
+  std::string component_registerName = _containerName + "/" + instanceName;
+
+  PyGILState_STATE gstate = PyGILState_Ensure();
+  PyObject *result = PyObject_CallMethod(_pyCont,
+                                         (char*)"create_component_instance",
+                                         (char*)"ssl",
+                                         CompName,
+                                         instanceName.c_str(),
+                                         0);
+  const char *ior;
+  const char *error;
+  PyArg_ParseTuple(result,"ss", &ior, &error);
+  reason = CORBA::string_dup(error);
+  char * _ior = CORBA::string_dup(ior);
+  Py_DECREF(result);
+  PyGILState_Release(gstate);
+
+  return _ior;
+}
+
+
 //=============================================================================
 //! Create a new component instance (C++ implementation)
 /*! 
@@ -997,10 +1049,10 @@ Engines_Container_i::createInstance(std::string genericRegisterName,
 
   if ( !Component_factory )
   {
-    INFOS( "Can't resolve symbol: " + factory_name );
+    MESSAGE( "Can't resolve symbol: " + factory_name );
 #ifndef WIN32
     reason=dlerror();
-    INFOS(reason);
+    MESSAGE(reason);
 #endif
     return Engines::EngineComponent::_nil() ;
   }
@@ -1586,10 +1638,10 @@ void Engines_Container_i::copyFile(Engines::Container_ptr container, const char*
       while (toFollow)
         {
           ctr++;
-          SCRUTE(ctr);
+          //SCRUTE(ctr);
           aBlock = fileTransfer->getBlock(fileId);
           toFollow = aBlock->length();
-          SCRUTE(toFollow);
+          //SCRUTE(toFollow);
           CORBA::Octet *buf = aBlock->get_buffer();
           fwrite(buf, sizeof(CORBA::Octet), toFollow, fp);
           delete aBlock;
@@ -1636,11 +1688,25 @@ Engines::PyNode_ptr Engines_Container_i::createPyNode(const char* nodeName, cons
     std::string astr=PyString_AsString(result);
     Py_DECREF(res);
     PyGILState_Release(gstate);
-
     if(ierr==0)
       {
-        CORBA::Object_var obj = _orb->string_to_object(astr.c_str());
-        node = Engines::PyNode::_narrow(obj);
+        Utils_Locker lck(&_mutexForDftPy);
+        CORBA::Object_var obj=_orb->string_to_object(astr.c_str());
+        node=Engines::PyNode::_narrow(obj);
+        std::map<std::string,Engines::PyNode_var>::iterator it(_dftPyNode.find(nodeName));
+        if(it==_dftPyNode.end())
+          {
+            _dftPyNode[nodeName]=node;
+          }
+        else
+          {
+            Engines::PyNode_var oldNode((*it).second);
+            if(!CORBA::is_nil(oldNode))
+              oldNode->UnRegister();
+            (*it).second=node;
+          }
+        if(!CORBA::is_nil(node))
+          node->Register();
         return node._retn();
       }
     else
@@ -1650,7 +1716,27 @@ Engines::PyNode_ptr Engines_Container_i::createPyNode(const char* nodeName, cons
         es.text = astr.c_str();
         throw SALOME::SALOME_Exception(es);
       }
+}
 
+//=============================================================================
+/*! \brief Retrieves the last created PyNode instance with createPyNode.
+ *
+ */
+//=============================================================================
+Engines::PyNode_ptr  Engines_Container_i::getDefaultPyNode(const char *nodeName)
+{
+  Utils_Locker lck(&_mutexForDftPy);
+  std::map<std::string,Engines::PyNode_var>::iterator it(_dftPyNode.find(nodeName));
+  if(it==_dftPyNode.end())
+    return Engines::PyNode::_nil();
+  else
+    {
+      Engines::PyNode_var tmpVar((*it).second);
+      if(!CORBA::is_nil(tmpVar))
+        return Engines::PyNode::_duplicate(tmpVar);
+      else
+        return Engines::PyNode::_nil();
+    }
 }
 
 //=============================================================================
@@ -1688,8 +1774,23 @@ Engines::PyScriptNode_ptr Engines_Container_i::createPyScriptNode(const char* no
 
     if(ierr==0)
       {
-        CORBA::Object_var obj = _orb->string_to_object(astr.c_str());
-        node = Engines::PyScriptNode::_narrow(obj);
+        Utils_Locker lck(&_mutexForDftPy);
+        CORBA::Object_var obj=_orb->string_to_object(astr.c_str());
+        node=Engines::PyScriptNode::_narrow(obj);
+        std::map<std::string,Engines::PyScriptNode_var>::iterator it(_dftPyScriptNode.find(nodeName));
+        if(it==_dftPyScriptNode.end())
+          {
+            _dftPyScriptNode[nodeName]=node;
+          }
+        else
+          {
+            Engines::PyScriptNode_var oldNode((*it).second);
+            if(!CORBA::is_nil(oldNode))
+              oldNode->UnRegister();
+            (*it).second=node;
+          }
+        if(!CORBA::is_nil(node))
+          node->Register();
         return node._retn();
       }
     else
@@ -1701,6 +1802,27 @@ Engines::PyScriptNode_ptr Engines_Container_i::createPyScriptNode(const char* no
       }
 }
 
+//=============================================================================
+/*! \brief Retrieves the last created PyScriptNode instance with createPyScriptNode.
+ *
+ */
+//=============================================================================
+Engines::PyScriptNode_ptr Engines_Container_i::getDefaultPyScriptNode(const char *nodeName)
+{
+  Utils_Locker lck(&_mutexForDftPy);
+  std::map<std::string,Engines::PyScriptNode_var>::iterator it(_dftPyScriptNode.find(nodeName));
+  if(it==_dftPyScriptNode.end())
+    return Engines::PyScriptNode::_nil();
+  else
+    {
+      Engines::PyScriptNode_var tmpVar((*it).second);
+      if(!CORBA::is_nil(tmpVar))
+        return Engines::PyScriptNode::_duplicate(tmpVar);
+      else
+        return Engines::PyScriptNode::_nil();
+    }
+}
+
 //=============================================================================
 /* int checkifexecutable(const char *filename)
 *
@@ -1777,7 +1899,7 @@ void Engines_Container_i::clearTemporaryFiles()
   std::list<std::string>::const_iterator it;
   for ( it = _tmp_files.begin(); it != _tmp_files.end(); ++it ) {
 #ifdef WIN32
-    std::string command = "del /F ";
+    std::string command = "del /F /P";
 #else
     std::string command = "rm -rf ";
 #endif