-// Copyright (C) 2007-2015 CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2023 CEA, EDF, OPEN CASCADE
//
// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
#include <stdio.h>
#include <time.h>
#include <sys/types.h>
+#include <memory>
#ifndef WIN32
#include <sys/time.h>
#include <dlfcn.h>
#include <unistd.h>
#include <sys/wait.h>
+#include <errno.h>
+#include <stdlib.h>
#else
#include <signal.h>
#include <process.h>
#include CORBA_SERVER_HEADER(SALOME_Component)
#include CORBA_SERVER_HEADER(SALOME_Exception)
#include <pthread.h> // must be before Python.h !
+#include "OpUtil.hxx"
#include "SALOME_Container_i.hxx"
#include "SALOME_Component_i.hxx"
#include "SALOME_FileRef_i.hxx"
#include "SALOME_FileTransfer_i.hxx"
#include "Salome_file_i.hxx"
#include "SALOME_NamingService.hxx"
+#include "SALOME_Fake_NamingService.hxx"
+#include "SALOME_Embedded_NamingService_Client.hxx"
+#include "SALOME_Embedded_NamingService.hxx"
#include "Basics_Utils.hxx"
+#include "PythonCppUtils.hxx"
#ifdef _XOPEN_SOURCE
#undef _XOPEN_SOURCE
#endif
#include <Python.h>
+#include <structmember.h>
#include "Container_init_python.hxx"
+#ifdef BOS26455_WITH_BOOST_PYTHON
+#include <boost/python.hpp>
+#endif
bool _Sleeping = false ;
#ifndef WIN32
#define LIB "lib"
+#ifdef __APPLE__
+#define ENGINESO "Engine.dylib"
+#else
#define ENGINESO "Engine.so"
+#endif
#else
#define LIB ""
#define ENGINESO "Engine.dll"
#define SLASH '/'
#endif
-std::map<std::string, int> Engines_Container_i::_cntInstances_map;
-std::map<std::string, void *> Engines_Container_i::_library_map;
-std::map<std::string, void *> Engines_Container_i::_toRemove_map;
-omni_mutex Engines_Container_i::_numInstanceMutex ;
+std::map<std::string, int> Abstract_Engines_Container_i::_cntInstances_map;
+std::map<std::string, void *> Abstract_Engines_Container_i::_library_map;
+std::map<std::string, void *> Abstract_Engines_Container_i::_toRemove_map;
+omni_mutex Abstract_Engines_Container_i::_numInstanceMutex ;
static PyObject* _pyCont;
*/
//=============================================================================
-Engines_Container_i::Engines_Container_i () :
-_numInstance(0),_id(0),_NS(0)
+Abstract_Engines_Container_i::Abstract_Engines_Container_i () :
+ _NS(nullptr),_id(nullptr),_numInstance(0)
{
}
//=============================================================================
/*!
-* Construtor to use
+* Constructor to use
*/
//=============================================================================
-Engines_Container_i::Engines_Container_i (CORBA::ORB_ptr orb,
- PortableServer::POA_ptr poa,
- char *containerName ,
- int argc , char* argv[],
- bool activAndRegist,
- bool isServantAloneInProcess
- ) :
- _numInstance(0),_isServantAloneInProcess(isServantAloneInProcess),_id(0),_NS(0)
+Abstract_Engines_Container_i::Abstract_Engines_Container_i (CORBA::ORB_ptr orb,
+ PortableServer::POA_ptr poa,
+ char *containerName ,
+ int argc , char* argv[],
+ SALOME_NamingService_Container_Abstract *ns,
+ bool isServantAloneInProcess
+ ) :
+ _NS(nullptr),_id(0),_numInstance(0),_isServantAloneInProcess(isServantAloneInProcess)
{
_pid = (long)getpid();
- if(activAndRegist)
+ if(ns)
ActSigIntHandler() ;
_argc = argc ;
// Pour les containers paralleles: il ne faut pas enregistrer et activer
// le container generique, mais le container specialise
- if(activAndRegist)
{
_id = _poa->activate_object(this);
- _NS = new SALOME_NamingService();
+ // key point : if ns is nullptr : this servant is alone in its process
+ // if ns is not null : this servant embedded into single process.
+ _NS = ns==nullptr ? new SALOME_NamingService : ns->clone();
_NS->init_orb( _orb ) ;
CORBA::Object_var obj=_poa->id_to_reference(*_id);
- Engines::Container_var pCont
- = Engines::Container::_narrow(obj);
+ Engines::Container_var pCont = Engines::Container::_narrow(obj);
_remove_ref();
- _containerName = _NS->BuildContainerNameForNS(containerName,
- hostname.c_str());
+ _containerName = SALOME_NamingService_Abstract::BuildContainerNameForNS(containerName, hostname.c_str());
SCRUTE(_containerName);
_NS->Register(pCont, _containerName.c_str());
- MESSAGE("Engines_Container_i::Engines_Container_i : Container name "
- << _containerName);
+ MESSAGE("Engines_Container_i::Engines_Container_i : Container name " << _containerName);
// Python:
// import SALOME_Container
//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);
+ {
+ AutoGIL gstate;
+ //// [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
- //Sleep(2000);
- //
- // first element is the path to Registry.dll, but it's wrong
- PyRun_SimpleString("import sys\n");
- PyRun_SimpleString("sys.path = sys.path[1:]\n");
+ // mpv: this is temporary solution: there is a unregular crash if not
+ //Sleep(2000);
+ //
+ // first element is the path to Registry.dll, but it's wrong
+ PyRun_SimpleString("import sys\n");
+ PyRun_SimpleString("sys.path = sys.path[1:]\n");
#endif
- PyRun_SimpleString("import SALOME_Container\n");
- PyRun_SimpleString((char*)myCommand.c_str());
- PyObject *mainmod = PyImport_AddModule("__main__");
- PyObject *globals = PyModule_GetDict(mainmod);
- _pyCont = PyDict_GetItemString(globals, "pyCont");
-
- //PyThreadState_Swap(NULL);
- //PyEval_ReleaseLock();
- PyGILState_Release(gstate);
+ PyRun_SimpleString("import SALOME_Container\n");
+ PyRun_SimpleString((char*)myCommand.c_str());
+ PyObject *mainmod = PyImport_AddModule("__main__");
+ PyObject *globals = PyModule_GetDict(mainmod);
+ _pyCont = PyDict_GetItemString(globals, "pyCont");
+ //PyThreadState_Swap(NULL);
+ //PyEval_ReleaseLock();
+ }
fileTransfer_i* aFileTransfer = new fileTransfer_i();
CORBA::Object_var obref=aFileTransfer->_this();
*/
//=============================================================================
-Engines_Container_i::~Engines_Container_i()
+Abstract_Engines_Container_i::~Abstract_Engines_Container_i()
{
- MESSAGE("Container_i::~Container_i()");
+ MESSAGE("Abstract_Container_i::~Abstract_Container_i()");
if(_id)
delete _id;
if(_NS)
delete _NS;
- if(!CORBA::is_nil(_dftPyNode))
- _dftPyNode->UnRegister();
- if(!CORBA::is_nil(_dftPyScriptNode))
- _dftPyScriptNode->UnRegister();
+ cleanAllPyScripts();
}
//=============================================================================
*/
//=============================================================================
-char* Engines_Container_i::name()
+char* Abstract_Engines_Container_i::name()
{
return CORBA::string_dup(_containerName.c_str()) ;
}
*/
//=============================================================================
-char* Engines_Container_i::workingdir()
+char* Abstract_Engines_Container_i::workingdir()
{
char wd[256];
getcwd (wd,256);
*/
//=============================================================================
-char* Engines_Container_i::logfilename()
+char* Abstract_Engines_Container_i::logfilename()
{
return CORBA::string_dup(_logfilename.c_str()) ;
}
//! Set container log file name
-void Engines_Container_i::logfilename(const char* name)
+void Abstract_Engines_Container_i::logfilename(const char* name)
{
_logfilename=name;
}
*/
//=============================================================================
-char* Engines_Container_i::getHostName()
+char* Abstract_Engines_Container_i::getHostName()
{
std::string s = Kernel_Utils::GetHostname();
// MESSAGE("Engines_Container_i::getHostName " << s);
*/
//=============================================================================
-CORBA::Long Engines_Container_i::getPID()
+CORBA::Long Abstract_Engines_Container_i::getPID()
{
return (CORBA::Long)getpid();
}
* CORBA method: check if servant is still alive
*/
//=============================================================================
-void Engines_Container_i::ping()
+void Abstract_Engines_Container_i::ping()
{
MESSAGE("Engines_Container_i::ping() pid "<< getpid());
}
+//=============================================================================
+//! Get number of CPU cores in the calculation node
+/*!
+* CORBA method: get number of CPU cores
+*/
+//=============================================================================
+
+CORBA::Long Abstract_Engines_Container_i::getNumberOfCPUCores()
+{
+ AutoGIL gstate;
+ PyObject *module = PyImport_ImportModuleNoBlock((char*)"salome_psutil");
+ PyObject *result = PyObject_CallMethod(module,
+ (char*)"getNumberOfCPUCores", NULL);
+ int n = PyLong_AsLong(result);
+ Py_DECREF(result);
+
+ return (CORBA::Long)n;
+}
+
+//=============================================================================
+//! Get a load of each CPU core in the calculation node
+/*!
+* CORBA method: get a load of each CPU core
+*/
+//=============================================================================
+namespace {
+ typedef struct
+ {
+ PyObject_HEAD
+ int softspace;
+ std::string *out;
+ } PyStdOut;
+
+ static void
+ PyStdOut_dealloc(PyStdOut *self)
+ {
+ PyObject_Del(self);
+ }
+
+ static PyObject*
+ PyStdOut_write(PyStdOut* self, PyObject* args)
+ {
+ char *c;
+ if (!PyArg_ParseTuple(args, "s", &c))
+ return NULL;
+
+ *(self->out) = *(self->out) + c;
+
+ Py_INCREF(Py_None);
+ return Py_None;
+ }
+
+ static PyMethodDef PyStdOut_methods[] =
+ {
+ {"write", (PyCFunction)PyStdOut_write, METH_VARARGS,
+ PyDoc_STR("write(string) -> None")},
+ {0, 0, 0, 0} /* sentinel */
+ };
+
+ static PyMemberDef PyStdOut_memberlist[] =
+ {
+ {(char*)"softspace", T_INT, offsetof(PyStdOut, softspace), 0,
+ (char*)"flag indicating that a space needs to be printed; used by print"},
+ {0, 0, 0, 0, 0} /* sentinel */
+ };
+
+ static PyTypeObject PyStdOut_Type =
+ {
+ /* The ob_type field must be initialized in the module init function
+ * to be portable to Windows without using C++. */
+ PyVarObject_HEAD_INIT(NULL, 0)
+ /* 0, */ /*ob_size*/
+ "PyOut", /*tp_name*/
+ sizeof(PyStdOut), /*tp_basicsize*/
+ 0, /*tp_itemsize*/
+ /* methods */
+ (destructor)PyStdOut_dealloc, /*tp_dealloc*/
+ 0, /*tp_print*/
+ 0, /*tp_getattr*/
+ 0, /*tp_setattr*/
+ 0, /*tp_compare*/
+ 0, /*tp_repr*/
+ 0, /*tp_as_number*/
+ 0, /*tp_as_sequence*/
+ 0, /*tp_as_mapping*/
+ 0, /*tp_hash*/
+ 0, /*tp_call*/
+ 0, /*tp_str*/
+ PyObject_GenericGetAttr, /*tp_getattro*/
+ /* softspace is writable: we must supply tp_setattro */
+ PyObject_GenericSetAttr, /* tp_setattro */
+ 0, /*tp_as_buffer*/
+ Py_TPFLAGS_DEFAULT, /*tp_flags*/
+ 0, /*tp_doc*/
+ 0, /*tp_traverse*/
+ 0, /*tp_clear*/
+ 0, /*tp_richcompare*/
+ 0, /*tp_weaklistoffset*/
+ 0, /*tp_iter*/
+ 0, /*tp_iternext*/
+ PyStdOut_methods, /*tp_methods*/
+ PyStdOut_memberlist, /*tp_members*/
+ 0, /*tp_getset*/
+ 0, /*tp_base*/
+ 0, /*tp_dict*/
+ 0, /*tp_descr_get*/
+ 0, /*tp_descr_set*/
+ 0, /*tp_dictoffset*/
+ 0, /*tp_init*/
+ 0, /*tp_alloc*/
+ 0, /*tp_new*/
+ 0, /*tp_free*/
+ 0, /*tp_is_gc*/
+ 0, /*tp_bases*/
+ 0, /*tp_mro*/
+ 0, /*tp_cache*/
+ 0, /*tp_subclasses*/
+ 0, /*tp_weaklist*/
+ 0, /*tp_del*/
+ 0, /*tp_version_tag*/
+ 0, /*tp_finalize*/
+ };
+
+ PyObject* newPyStdOut(std::string& out)
+ {
+ PyStdOut* self = PyObject_New(PyStdOut, &PyStdOut_Type);
+ if (self) {
+ self->softspace = 0;
+ self->out=&out;
+ }
+ return (PyObject*)self;
+ }
+
+ std::string parseException()
+ {
+ std::string error;
+ if (PyErr_Occurred())
+ {
+#ifdef BOS26455_WITH_BOOST_PYTHON
+ PyObject *ptype = nullptr;
+ PyObject *pvalue = nullptr;
+ PyObject *ptraceback = nullptr;
+ PyErr_Fetch(&ptype, &pvalue, &ptraceback);
+ if (ptype == nullptr)
+ return std::string("Null exception type");
+ PyErr_NormalizeException(&ptype, &pvalue, &ptraceback);
+ if (ptraceback != nullptr)
+ PyException_SetTraceback(pvalue, ptraceback);
+ boost::python::handle<> htype(ptype);
+ boost::python::handle<> hvalue(boost::python::allow_null(pvalue));
+ boost::python::handle<> htraceback(boost::python::allow_null(ptraceback));
+ boost::python::object traceback = boost::python::import("traceback");
+ boost::python::object format_exc = traceback.attr("format_exception");
+ boost::python::object formatted = format_exc(htype, hvalue, htraceback);
+ error = boost::python::extract<std::string>(boost::python::str("\n").join(formatted));
+#else
+ PyObject* new_stderr = newPyStdOut(error);
+ PyObject* old_stderr = PySys_GetObject((char*)"stderr");
+ Py_INCREF(old_stderr);
+ PySys_SetObject((char*)"stderr", new_stderr);
+ PyErr_Print();
+ PySys_SetObject((char*)"stderr", old_stderr);
+ Py_DECREF(new_stderr);
+#endif
+ }
+ return error;
+ }
+}
+
+Engines::vectorOfDouble* Abstract_Engines_Container_i::loadOfCPUCores()
+{
+ AutoGIL gstate;
+ PyObject *module = PyImport_ImportModuleNoBlock((char*)"salome_psutil");
+ PyObject *result = PyObject_CallMethod(module,
+ (char*)"loadOfCPUCores", "s",
+ _load_script.c_str());
+ if (PyErr_Occurred())
+ {
+ std::string error = parseException();
+ PyErr_Print();
+ SALOME::ExceptionStruct es;
+ es.type = SALOME::INTERNAL_ERROR;
+ es.text = CORBA::string_dup(error.c_str());
+ throw SALOME::SALOME_Exception(es);
+ }
+
+ int n = this->getNumberOfCPUCores();
+ if (!PyList_Check(result) || PyList_Size(result) != n) {
+ // bad number of cores
+ Py_DECREF(result);
+ SALOME::ExceptionStruct es;
+ es.type = SALOME::INTERNAL_ERROR;
+ es.text = "wrong number of cores";
+ throw SALOME::SALOME_Exception(es);
+ }
+
+ Engines::vectorOfDouble_var loads = new Engines::vectorOfDouble;
+ loads->length(n);
+ for (Py_ssize_t i = 0; i < PyList_Size(result); ++i) {
+ PyObject* item = PyList_GetItem(result, i);
+ double foo = PyFloat_AsDouble(item);
+ if (foo < 0.0 || foo > 1.0)
+ {
+ // value not in [0, 1] range
+ Py_DECREF(result);
+ SALOME::ExceptionStruct es;
+ es.type = SALOME::INTERNAL_ERROR;
+ es.text = "load not in [0, 1] range";
+ throw SALOME::SALOME_Exception(es);
+ }
+ loads[i] = foo;
+ }
+
+ Py_DECREF(result);
+
+ return loads._retn();
+}
+
+//=============================================================================
+//! Set custom script to calculate a load of each CPU core
+/*!
+* CORBA method: Set custom script to calculate CPU load
+* \param script Python script to execute
+*/
+//=============================================================================
+
+void Abstract_Engines_Container_i::setPyScriptForCPULoad(const char *script)
+{
+ _load_script = script;
+}
+
+//=============================================================================
+//! Nullify custom script to calculate each CPU core's load
+/*!
+* CORBA method: reset script for load calculation to default implementation
+*/
+//=============================================================================
+
+void Abstract_Engines_Container_i::resetScriptForCPULoad()
+{
+ _load_script = "";
+}
+
+//=============================================================================
+//! Get total physical memory of calculation node, in megabytes
+/*!
+* CORBA method: get total physical memory of calculation node
+*/
+//=============================================================================
+
+CORBA::Long Abstract_Engines_Container_i::getTotalPhysicalMemory()
+{
+ AutoGIL gstate;
+ PyObject *module = PyImport_ImportModuleNoBlock((char*)"salome_psutil");
+ PyObject *result = PyObject_CallMethod(module,
+ (char*)"getTotalPhysicalMemory", NULL);
+ int n = PyLong_AsLong(result);
+ Py_DECREF(result);
+
+ return (CORBA::Long)n;
+}
+
+//=============================================================================
+//! Get used physical memory of calculation node, in megabytes
+/*!
+* CORBA method: get used physical memory of calculation node
+*/
+//=============================================================================
+
+CORBA::Long Abstract_Engines_Container_i::getTotalPhysicalMemoryInUse()
+{
+ AutoGIL gstate;
+ PyObject *module = PyImport_ImportModuleNoBlock((char*)"salome_psutil");
+ PyObject *result = PyObject_CallMethod(module,
+ (char*)"getTotalPhysicalMemoryInUse", NULL);
+ int n = PyLong_AsLong(result);
+ Py_DECREF(result);
+
+ return (CORBA::Long)n;
+}
+
+//=============================================================================
+//! Obtain physical memory, used by the current process, in megabytes.
+/*!
+* CORBA method: get physical memory, used by the current process
+*/
+//=============================================================================
+
+CORBA::Long Abstract_Engines_Container_i::getTotalPhysicalMemoryInUseByMe()
+{
+ AutoGIL gstate;
+ PyObject *module = PyImport_ImportModuleNoBlock((char*)"salome_psutil");
+ PyObject *result = PyObject_CallMethod(module,
+ (char*)"getTotalPhysicalMemoryInUseByMe", NULL);
+ int n = PyLong_AsLong(result);
+ Py_DECREF(result);
+
+ return (CORBA::Long)n;
+}
+
//=============================================================================
//! Shutdown the container
/*!
* - orb shutdown if no other servants in the process
*/
//=============================================================================
-void Engines_Container_i::Shutdown()
+void Abstract_Engines_Container_i::Shutdown()
{
MESSAGE("Engines_Container_i::Shutdown()");
*/
std::map<std::string, Engines::EngineComponent_var>::iterator itm;
for (itm = _listInstances_map.begin(); itm != _listInstances_map.end(); itm++)
+ {
+ try
{
- try
- {
- itm->second->destroy();
- }
- catch(const CORBA::Exception& e)
- {
- // ignore this entry and continue
- }
- catch(...)
- {
- // ignore this entry and continue
- }
+ itm->second->destroy();
+ }
+ catch(const CORBA::Exception&)
+ {
+ // ignore this entry and continue
+ }
+ catch(...)
+ {
+ // ignore this entry and continue
}
+ }
_listInstances_map.clear();
- _NS->Destroy_FullDirectory(_containerName.c_str());
- _NS->Destroy_Name(_containerName.c_str());
+ // NS unregistering may throw in SSL mode if master process hosting SALOME_Embedded_NamingService servant has vanished
+ // In this case it's skip it and still continue.
+ try
+ {
+ _NS->Destroy_FullDirectory(_containerName.c_str());
+ _NS->Destroy_Name(_containerName.c_str());
+ }
+ catch(...)
+ {
+ }
+ //
+ this->cleanAllPyScripts();
+ //
if(_isServantAloneInProcess)
{
MESSAGE("Effective Shutdown of container Begins...");
* CORBA method
* \param componentName component name
* \param reason explains error when load fails
-* \return true if dlopen successfull or already done, false otherwise
+* \return true if dlopen successful or already done, false otherwise
*/
//=============================================================================
bool
-Engines_Container_i::load_component_Library(const char* componentName, CORBA::String_out reason)
+Abstract_Engines_Container_i::load_component_Library(const char* componentName, CORBA::String_out reason)
{
//=================================================================
//=================================================================
std::string retso;
if(load_component_CppImplementation(componentName,retso))
- {
- reason=CORBA::string_dup("");
- return true;
- }
+ {
+ reason=CORBA::string_dup("");
+ return true;
+ }
else if(retso != "ImplementationNotFound")
- {
- reason=CORBA::string_dup(retso.c_str());
- return false;
- }
+ {
+ reason=CORBA::string_dup(retso.c_str());
+ return false;
+ }
retso="Component ";
retso+=componentName;
//=================================================================
std::string retpy;
if(load_component_PythonImplementation(componentName,retpy))
- {
- reason=CORBA::string_dup("");
- return true;
- }
+ {
+ reason=CORBA::string_dup("");
+ return true;
+ }
else if(retpy != "ImplementationNotFound")
- {
- reason=CORBA::string_dup(retpy.c_str());
- return false;
- }
+ {
+ reason=CORBA::string_dup(retpy.c_str());
+ return false;
+ }
retpy="Component ";
retpy+=componentName;
//=================================================================
std::string retex;
if(load_component_ExecutableImplementation(componentName,retex))
- {
- reason=CORBA::string_dup("");
- return true;
- }
+ {
+ reason=CORBA::string_dup("");
+ return true;
+ }
else if(retex != "ImplementationNotFound")
- {
- reason=CORBA::string_dup(retex.c_str());
- return false;
- }
+ {
+ reason=CORBA::string_dup(retex.c_str());
+ return false;
+ }
retex="Component ";
retex+=componentName;
* C++ method:
* \param componentName the name of the component (COMPONENT, for example)
* \param reason explains error when load fails
-* \return true if loading is successfull or already done, false otherwise
+* \return true if loading is successful or already done, false otherwise
*/
//=============================================================================
bool
-Engines_Container_i::load_component_CppImplementation(const char* componentName, std::string& reason)
+Abstract_Engines_Container_i::load_component_CppImplementation(const char* componentName, std::string& reason)
{
std::string aCompName(componentName);
std::string impl_name = std::string(LIB) + aCompName + ENGINESO;
// (see decInstanceCnt, finalize_removal))
if (_toRemove_map.count(impl_name) != 0) _toRemove_map.erase(impl_name);
if (_library_map.count(impl_name) != 0)
- {
- MESSAGE("Library " << impl_name << " already loaded");
- _numInstanceMutex.unlock();
- reason="";
- return true;
- }
+ {
+ MESSAGE("Library " << impl_name << " already loaded");
+ _numInstanceMutex.unlock();
+ reason="";
+ return true;
+ }
_numInstanceMutex.unlock();
#ifndef WIN32
void* handle;
- handle = dlopen( impl_name.c_str() , RTLD_NOW ) ;
+ handle = dlopen( impl_name.c_str() , RTLD_NOW | RTLD_GLOBAL ) ;
if ( !handle )
- {
- //not loadable. Try to find the lib file in LD_LIBRARY_PATH
- std::string path;
+ {
+ //not loadable. Try to find the lib file in LD_LIBRARY_PATH
+ std::string path;
+#ifdef __APPLE__
+ char* p=getenv("DYLD_LIBRARY_PATH");
+#else
char* p=getenv("LD_LIBRARY_PATH");
+#endif
if(p)path=p;
path=path+SEP+"/usr/lib"+SEP+"/lib";
//continue with other implementation
reason="ImplementationNotFound";
return false;
- }
}
+ }
#else
HINSTANCE handle;
- handle = LoadLibrary( impl_name.c_str() );
+#ifdef UNICODE
+ std::wstring libToLoad = Kernel_Utils::utf8_decode_s( impl_name );
+#else
+ std::string libToLoad = impl_name;
+#endif
+ handle = LoadLibrary(libToLoad.c_str() );
if ( !handle )
- {
- reason="ImplementationNotFound";
- }
+ {
+ reason="ImplementationNotFound";
+ }
#endif
if ( handle )
- {
- _numInstanceMutex.lock();
- _library_map[impl_name] = handle;
- _numInstanceMutex.unlock();
- reason="";
- return true;
- }
+ {
+ _numInstanceMutex.lock();
+ _library_map[impl_name] = handle;
+ _numInstanceMutex.unlock();
+ reason="";
+ return true;
+ }
return false;
* C++ method:
* \param componentName name of the component
* \param reason explains error when load fails
-* \return true if loading is successfull or already done, false otherwise
+* \return true if loading is successful or already done, false otherwise
*/
//=============================================================================
bool
-Engines_Container_i::load_component_PythonImplementation(const char* componentName, std::string& reason)
+Abstract_Engines_Container_i::load_component_PythonImplementation(const char* componentName, std::string& reason)
{
std::string aCompName(componentName);
_numInstanceMutex.lock() ; // lock to be alone (stl container write)
if (_library_map.count(aCompName) != 0)
- {
- _numInstanceMutex.unlock() ;
- reason="";
- return true; // Python Component, already imported
- }
+ {
+ _numInstanceMutex.unlock() ;
+ reason="";
+ return true; // Python Component, already imported
+ }
_numInstanceMutex.unlock() ;
- PyGILState_STATE gstate = PyGILState_Ensure();
- PyObject *result = PyObject_CallMethod(_pyCont,
- (char*)"import_component",
- (char*)"s",componentName);
-
- reason=PyString_AsString(result);
- Py_XDECREF(result);
- SCRUTE(reason);
- PyGILState_Release(gstate);
+ {
+ AutoGIL gstate;
+ PyObject *result = PyObject_CallMethod(_pyCont,
+ (char*)"import_component",
+ (char*)"s",componentName);
+
+ reason=PyUnicode_AsUTF8(result);
+ Py_XDECREF(result);
+ SCRUTE(reason);
+ }
if (reason=="")
- {
- //Python component has been loaded (import componentName)
- _numInstanceMutex.lock() ; // lock to be alone (stl container write)
- _library_map[aCompName] = (void *)_pyCont; // any non O value OK
- _numInstanceMutex.unlock() ;
- MESSAGE("import Python: "<< aCompName <<" OK");
- return true;
- }
+ {
+ //Python component has been loaded (import componentName)
+ _numInstanceMutex.lock() ; // lock to be alone (stl container write)
+ _library_map[aCompName] = (void *)_pyCont; // any non O value OK
+ _numInstanceMutex.unlock() ;
+ MESSAGE("import Python: "<< aCompName <<" OK");
+ return true;
+ }
else if(reason=="ImplementationNotFound")
- {
- //Python implementation has not been found. Continue with other implementation
- reason="ImplementationNotFound";
- }
+ {
+ //Python implementation has not been found. Continue with other implementation
+ reason="ImplementationNotFound";
+ }
else
- {
- //Python implementation has been found but loading has failed
- std::cerr << reason << std::endl;
- }
+ {
+ //Python implementation has been found but loading has failed
+ std::cerr << reason << std::endl;
+ }
return false;
}
* C++ method:
* \param componentName name of the component
* \param reason explains error when load fails
-* \return true if loading is successfull or already done, false otherwise
+* \return true if loading is successful or already done, false otherwise
*/
//=============================================================================
bool
-Engines_Container_i::load_component_ExecutableImplementation(const char* componentName, std::string& reason)
+Abstract_Engines_Container_i::load_component_ExecutableImplementation(const char* componentName, std::string& reason)
{
std::string aCompName(componentName);
std::string executable=aCompName+".exe";
if(p)path=p;
if (findpathof(path, pth, executable))
+ {
+ if(checkifexecutable(pth))
{
- if(checkifexecutable(pth))
- {
- _numInstanceMutex.lock() ; // lock to be alone (stl container write)
- _library_map[executable] = (void *)1; // any non O value OK
- _numInstanceMutex.unlock() ;
- MESSAGE("import executable: "<< pth <<" OK");
- reason="";
- return true;
- }
- reason="Component ";
- reason+=aCompName;
- reason+=": implementation found ";
- reason+=pth;
- reason+=" but it is not executable";
- std::cerr << reason << std::endl;
+ _numInstanceMutex.lock() ; // lock to be alone (stl container write)
+ _library_map[executable] = (void *)1; // any non O value OK
+ _numInstanceMutex.unlock() ;
+ MESSAGE("import executable: "<< pth <<" OK");
+ reason="";
+ return true;
}
+ reason="Component ";
+ reason+=aCompName;
+ reason+=": implementation found ";
+ reason+=pth;
+ reason+=" but it is not executable";
+ std::cerr << reason << std::endl;
+ }
else
- {
- reason="ImplementationNotFound";
- }
+ {
+ reason="ImplementationNotFound";
+ }
return false;
}
//! Create a new component instance
/*!
* CORBA method: Creates a new servant instance of a component.
-* The servant registers itself to naming service and Registry.
+* The servant registers itself to naming service and Registry.tdlib
* \param genericRegisterName Name of the component instance to register
* in Registry & Name Service (without _inst_n suffix)
-* \param studyId 0 for multiStudy instance,
-* study Id (>0) otherwise
* \return a loaded component
*/
//=============================================================================
Engines::EngineComponent_ptr
-Engines_Container_i::create_component_instance(const char*genericRegisterName,
- CORBA::Long studyId)
+Abstract_Engines_Container_i::create_component_instance(const char*genericRegisterName)
{
Engines::FieldsDict_var env = new Engines::FieldsDict;
char* reason;
Engines::EngineComponent_ptr compo =
- create_component_instance_env(genericRegisterName, studyId, env, reason);
+ create_component_instance_env(genericRegisterName, env, reason);
CORBA::string_free(reason);
return compo;
}
+void EffectiveOverrideEnvironment( const Engines::FieldsDict& env )
+{
+ MESSAGE("Positionning environment on container ");
+ for (CORBA::ULong i=0; i < env.length(); i++)
+ {
+ if (env[i].value.type()->kind() == CORBA::tk_string)
+ {
+ const char* value;
+ env[i].value >>= value;
+ MESSAGE( env[i].key << " = " << value);
+#ifndef WIN32
+ if( setenv(env[i].key,value,1) != 0 )
+ {
+ int errsv = errno;
+ std::string sErr( strerror( errsv) );
+ MESSAGE(sErr);
+ }
+#endif
+ }
+ }
+}
+
+std::vector< std::pair<std::string,std::string> > GetOSEnvironment()
+{
+ std::vector< std::pair<std::string,std::string> > ret;
+#ifndef WIN32
+ char **envPt( environ );
+ for(;*envPt != nullptr; ++envPt)
+ {
+ std::string s( *envPt );
+ auto pos = s.find_first_of('=');
+ std::string k( s.substr(0,pos) ),v( s.substr(pos+1) );
+ ret.emplace_back( std::pair<std::string,std::string>(k,v) );
+ }
+#endif
+ return ret;
+}
+
+void Abstract_Engines_Container_i::override_environment( const Engines::FieldsDict& env )
+{
+ EffectiveOverrideEnvironment(env);
+}
+
+Engines::FieldsDict *Abstract_Engines_Container_i::get_os_environment()
+{
+ std::unique_ptr<Engines::FieldsDict> ret( new Engines::FieldsDict );
+ std::vector< std::pair<std::string,std::string> > retCpp( GetOSEnvironment() );
+ auto sz = retCpp.size();
+ ret->length( sz );
+ for(auto i = 0 ; i < sz ; ++i)
+ {
+ (*ret)[i].key = CORBA::string_dup( retCpp[i].first.c_str() );
+ (*ret)[i].value <<= CORBA::string_dup( retCpp[i].second.c_str() );
+ }
+ return ret.release();
+}
+
//=============================================================================
//! Create a new component instance with environment variables specified
/*!
* The servant registers itself to naming service and Registry.
* \param genericRegisterName Name of the component instance to register
* in Registry & Name Service (without _inst_n suffix)
-* \param studyId 0 for multiStudy instance,
-* study Id (>0) otherwise
* \param env dict of env variables
* \param reason explains error when create_component_instance_env fails
* \return a loaded component
*/
//=============================================================================
Engines::EngineComponent_ptr
-Engines_Container_i::create_component_instance_env(const char*genericRegisterName,
- CORBA::Long studyId,
+Abstract_Engines_Container_i::create_component_instance_env(const char*genericRegisterName,
const Engines::FieldsDict& env,
CORBA::String_out reason)
{
- if (studyId < 0)
- {
- INFOS("studyId must be > 0 for mono study instance, =0 for multiStudy");
- reason=CORBA::string_dup("studyId must be > 0 for mono study instance, =0 for multiStudy");
- return Engines::EngineComponent::_nil() ;
- }
-
std::string error;
if (_library_map.count(genericRegisterName) != 0)
- {
- // It's a Python component
- Engines::EngineComponent_ptr compo = createPythonInstance(genericRegisterName, studyId, error);
- reason=CORBA::string_dup(error.c_str());
- return compo;
- }
+ {
+ // It's a Python component
+ Engines::EngineComponent_ptr compo = createPythonInstance(genericRegisterName, error);
+ reason=CORBA::string_dup(error.c_str());
+ return compo;
+ }
std::string impl_name = std::string(LIB) + genericRegisterName + ENGINESO;
if (_library_map.count(impl_name) != 0)
- {
- // It's a C++ component
- void* handle = _library_map[impl_name];
- Engines::EngineComponent_ptr compo = createInstance(genericRegisterName, handle, studyId, error);
- reason=CORBA::string_dup(error.c_str());
- return compo;
- }
+ {
+ // It's a C++ component
+ void* handle = _library_map[impl_name];
+ Engines::EngineComponent_ptr compo = createInstance(genericRegisterName, handle, error);
+ reason=CORBA::string_dup(error.c_str());
+ return compo;
+ }
impl_name = std::string(genericRegisterName) + ".exe";
if (_library_map.count(impl_name) != 0)
- {
- //It's an executable component
- Engines::EngineComponent_ptr compo = createExecutableInstance(genericRegisterName, studyId, env, error);
- reason=CORBA::string_dup(error.c_str());
- return compo;
- }
+ {
+ //It's an executable component
+ Engines::EngineComponent_ptr compo = createExecutableInstance(genericRegisterName, env, error);
+ reason=CORBA::string_dup(error.c_str());
+ return compo;
+ }
error="load_component_Library has probably not been called for component: ";
error += genericRegisterName;
//! Create a new component instance (Executable implementation)
/*!
* \param CompName Name of the component instance
-* \param studyId 0 for multiStudy instance,
-* study Id (>0) otherwise
* \param env dict of env variables
* \param reason explains error when creation fails
* \return a loaded component
*/
//=============================================================================
Engines::EngineComponent_ptr
-Engines_Container_i::createExecutableInstance(std::string CompName, int studyId,
- const Engines::FieldsDict& env,
- std::string& reason)
+Abstract_Engines_Container_i::createExecutableInstance(std::string CompName,
+ const Engines::FieldsDict& env,
+ std::string& reason)
{
Engines::EngineComponent_var iobject = Engines::EngineComponent::_nil() ;
int status;
pid_t pid = fork();
if(pid == 0) // child
- {
- for (CORBA::ULong i=0; i < env.length(); i++)
- {
- if (env[i].value.type()->kind() == CORBA::tk_string)
- {
- const char* value;
- env[i].value >>= value;
- std::string s(env[i].key);
- s+='=';
- s+=value;
- putenv(strdup(s.c_str()));
- }
- }
+ {
+ EffectiveOverrideEnvironment(env);
- execl("/bin/sh", "sh", "-c", command.c_str() , (char *)0);
- status=-1;
- }
+ execl("/bin/sh", "sh", "-c", command.c_str() , (char *)0);
+ status=-1;
+ }
else if(pid < 0) // failed to fork
- {
- status=-1;
- }
+ {
+ status=-1;
+ }
else //parent
+ {
+ pid_t tpid;
+ do
{
- pid_t tpid;
- do
- {
- tpid = wait(&status);
- } while (tpid != pid);
- }
+ tpid = wait(&status);
+ } while (tpid != pid);
+ }
#else
// launch component with a system call
int status=system(command.c_str());
//! Create a new component instance (Python implementation)
/*!
* \param CompName Name of the component instance
-* \param studyId 0 for multiStudy instance,
-* study Id (>0) otherwise
* \param reason explains error when creation fails
* \return a loaded component
*/
//=============================================================================
Engines::EngineComponent_ptr
-Engines_Container_i::createPythonInstance(std::string CompName, int studyId,
+Abstract_Engines_Container_i::createPythonInstance(std::string CompName,
std::string& reason)
{
Engines::EngineComponent_var iobject = Engines::EngineComponent::_nil() ;
sprintf( aNumI , "%d" , numInstance ) ;
std::string instanceName = 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.c_str(),
- instanceName.c_str(),
- studyId);
- const char *ior;
- const char *error;
- PyArg_ParseTuple(result,"ss", &ior, &error);
- std::string iors = ior;
- reason=error;
- Py_DECREF(result);
- PyGILState_Release(gstate);
+ std::string iors;
+ {
+ AutoGIL gstate;
+ PyObject *result = PyObject_CallMethod(_pyCont,
+ (char*)"create_component_instance",
+ (char*)"ss",
+ CompName.c_str(),
+ instanceName.c_str());
+ const char *ior;
+ const char *error;
+ PyArg_ParseTuple(result,"ss", &ior, &error);
+ iors = ior;
+ reason=error;
+ Py_DECREF(result);
+ }
if( iors!="" )
- {
- CORBA::Object_var obj = _orb->string_to_object(iors.c_str());
- iobject = Engines::EngineComponent::_narrow( obj ) ;
- _listInstances_map[instanceName] = iobject;
- }
+ {
+ CORBA::Object_var obj = _orb->string_to_object(iors.c_str());
+ iobject = Engines::EngineComponent::_narrow( obj ) ;
+ _listInstances_map[instanceName] = iobject;
+ }
return iobject._retn();
}
char *
-Engines_Container_i::create_python_service_instance(const char * CompName,
+Abstract_Engines_Container_i::create_python_service_instance(const char * CompName,
CORBA::String_out reason)
{
CORBA::Object_var object = CORBA::Object::_nil();
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);
- Py_DECREF(result);
- PyGILState_Release(gstate);
-
- return CORBA::string_dup(ior);
+ char * _ior = nullptr;
+ {
+ AutoGIL gstate;
+ PyObject *result = PyObject_CallMethod(_pyCont,
+ (char*)"create_component_instance",
+ (char*)"ss",
+ CompName,
+ instanceName.c_str());
+ const char *ior;
+ const char *error;
+ PyArg_ParseTuple(result,"ss", &ior, &error);
+ reason = CORBA::string_dup(error);
+ _ior = CORBA::string_dup(ior);
+ Py_DECREF(result);
+ }
+ return _ior;
}
* in Registry & Name Service,
* (without _inst_n suffix, like "COMPONENT")
* \param handle loaded library handle
-* \param studyId 0 for multiStudy instance,
-* study Id (>0) otherwise
* \param reason explains error when creation fails
* \return a loaded component
*
*/
//=============================================================================
Engines::EngineComponent_ptr
-Engines_Container_i::createInstance(std::string genericRegisterName,
+Abstract_Engines_Container_i::createInstance(std::string genericRegisterName,
void *handle,
- int studyId,
std::string& reason)
{
// --- find the factory
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() ;
}
std::string component_registerName =
_containerName + "/" + instanceName;
- // --- Instanciate required CORBA object
+ // --- Instantiate required CORBA object
PortableServer::ObjectId *id ; //not owner, do not delete (nore use var)
id = (Component_factory) ( _orb, _poa, _id, instanceName.c_str(),
aGenRegisterName.c_str() ) ;
if (id == NULL)
- {
- reason="Can't get ObjectId from factory";
- INFOS(reason);
- return iobject._retn();
- }
+ {
+ reason="Can't get ObjectId from factory";
+ INFOS(reason);
+ return iobject._retn();
+ }
- // --- get reference & servant from id
+ // --- get reference from id
CORBA::Object_var obj = _poa->id_to_reference(*id);
iobject = Engines::EngineComponent::_narrow( obj ) ;
- Engines_Component_i *servant =
- dynamic_cast<Engines_Component_i*>(_poa->reference_to_servant(iobject));
- ASSERT(servant);
- //SCRUTE(servant->_refcount_value());
_numInstanceMutex.lock() ; // lock to be alone (stl container write)
_listInstances_map[instanceName] = iobject;
_cntInstances_map[aGenRegisterName] += 1;
_numInstanceMutex.unlock() ;
SCRUTE(aGenRegisterName);
SCRUTE(_cntInstances_map[aGenRegisterName]);
- servant->setStudyId(studyId);
- servant->_remove_ref(); // do not need servant any more (remove ref from reference_to_servant)
- //SCRUTE(servant->_refcount_value());
// --- register the engine under the name
// containerName(.dir)/instanceName(.object)
}
catch (...)
{
- reason="Container_i::createInstance exception catched";
+ reason="Container_i::createInstance exception caught";
INFOS(reason) ;
}
return iobject._retn();
* CORBA method: Finds a servant instance of a component
* \param registeredName Name of the component in Registry or Name Service,
* without instance suffix number
-* \param studyId 0 if instance is not associated to a study,
-* >0 otherwise (== study id)
-* \return the first instance found with same studyId
+* \return the first found instance
*/
//=============================================================================
Engines::EngineComponent_ptr
-Engines_Container_i::find_component_instance( const char* registeredName,
- CORBA::Long studyId)
+Abstract_Engines_Container_i::find_component_instance( const char* registeredName)
{
Engines::EngineComponent_var anEngine = Engines::EngineComponent::_nil();
std::map<std::string,Engines::EngineComponent_var>::iterator itm =_listInstances_map.begin();
if (instance.find(registeredName) == 0)
{
anEngine = (*itm).second;
- if (studyId == anEngine->getStudyId())
- {
- return anEngine._retn();
- }
+ return anEngine._retn();
}
itm++;
}
*/
//=============================================================================
-void Engines_Container_i::remove_impl(Engines::EngineComponent_ptr component_i)
+void Abstract_Engines_Container_i::remove_impl(Engines::EngineComponent_ptr component_i)
{
ASSERT(! CORBA::is_nil(component_i));
std::string instanceName = component_i->instanceName() ;
* CORBA method: Discharges unused libraries from the container.
*/
//=============================================================================
-void Engines_Container_i::finalize_removal()
+void Abstract_Engines_Container_i::finalize_removal()
{
MESSAGE("finalize unload : dlclose");
_numInstanceMutex.lock(); // lock to be alone
*
*/
//=============================================================================
-void Engines_Container_i::decInstanceCnt(std::string genericRegisterName)
+void Abstract_Engines_Container_i::decInstanceCnt(std::string genericRegisterName)
{
if(_cntInstances_map.count(genericRegisterName)==0)
return;
//=============================================================================
Engines::EngineComponent_ptr
-Engines_Container_i::load_impl( const char* genericRegisterName,
- const char* componentName )
+Abstract_Engines_Container_i::load_impl( const char* genericRegisterName,
+ const char* /*componentName*/ )
{
char* reason;
std::string impl_name = std::string(LIB) + genericRegisterName + ENGINESO;
return iobject._retn();
}
+Engines::EmbeddedNamingService_ptr Abstract_Engines_Container_i::get_embedded_NS_if_ssl()
+{
+ SALOME_Embedded_NamingService_Client *nsc(dynamic_cast<SALOME_Embedded_NamingService_Client *>(this->_NS));
+ if(nsc)
+ {
+ Engines::EmbeddedNamingService_var obj = nsc->GetObject();
+ return Engines::EmbeddedNamingService::_duplicate(obj);
+ }
+ else
+ {
+ SALOME_Fake_NamingService *fns(dynamic_cast<SALOME_Fake_NamingService *>(this->_NS));
+ if(fns)
+ {
+ Engines::EmbeddedNamingService_var ret = GetEmbeddedNamingService();
+ return ret._retn();
+ }
+ else
+ return Engines::EmbeddedNamingService::_nil();
+ }
+}
+
//=============================================================================
//! Finds an already existing component instance or create a new instance
/*!
//=============================================================================
Engines::EngineComponent_ptr
-Engines_Container_i::find_or_create_instance(std::string genericRegisterName,
- std::string componentLibraryName)
+Abstract_Engines_Container_i::find_or_create_instance(std::string genericRegisterName,
+ std::string componentLibraryName)
{
std::string aGenRegisterName = genericRegisterName;
std::string impl_name = componentLibraryName;
{
iobject = createInstance(genericRegisterName,
handle,
- 0,
- reason); // force multiStudy instance here !
+ reason);
}
else
{
iobject = Engines::EngineComponent::_narrow( obj ) ;
- Engines_Component_i *servant =
- dynamic_cast<Engines_Component_i*>
- (_poa->reference_to_servant(iobject));
- ASSERT(servant)
- int studyId = servant->getStudyId();
- ASSERT (studyId >= 0);
- if (studyId == 0) // multiStudy instance, OK
- {
- // No ReBind !
- MESSAGE(component_registerBase.c_str()<<" already bound");
- }
- else // monoStudy instance: NOK
- {
- iobject = Engines::EngineComponent::_nil();
- INFOS("load_impl & find_component_instance methods "
- << "NOT SUITABLE for mono study components");
- }
}
}
catch (...)
{
- INFOS( "Container_i::load_impl catched" ) ;
+ INFOS( "Container_i::load_impl caught" ) ;
}
return iobject._retn();
}
* Retrieves only with container naming convention if it is a python container
*/
//=============================================================================
-bool Engines_Container_i::isPythonContainer(const char* ContainerName)
+bool Abstract_Engines_Container_i::isPythonContainer(const char* ContainerName)
{
bool ret=false;
- int len=strlen(ContainerName);
+ size_t len=strlen(ContainerName);
if(len>=2)
if(strcmp(ContainerName+len-2,"Py")==0)
ret=true;
* To remove : never returns !
*/
//=============================================================================
-bool Engines_Container_i::Kill_impl()
+bool Abstract_Engines_Container_i::Kill_impl()
{
MESSAGE("Engines_Container_i::Kill() pid "<< getpid() << " containerName "
<< _containerName.c_str() << " machineName "
void CallCancelThread() ;
#ifndef WIN32
-void SigIntHandler(int what ,
+void SigIntHandler(int /*what*/ ,
siginfo_t * siginfo ,
- void * toto )
+ void * /*toto*/ )
{
//PAL9042 JR : during the execution of a Signal Handler (and of methods called through Signal Handlers)
// use of streams (and so on) should never be used because :
*/
//=============================================================================
Engines::fileRef_ptr
-Engines_Container_i::createFileRef(const char* origFileName)
+Abstract_Engines_Container_i::createFileRef(const char* origFileName)
{
std::string origName(origFileName);
Engines::fileRef_var theFileRef = Engines::fileRef::_nil();
if (origName[0] != '/')
{
- INFOS("path of file to copy must be an absolute path begining with '/'");
+ INFOS("path of file to copy must be an absolute path beginning with '/'");
return Engines::fileRef::_nil();
}
*/
//=============================================================================
Engines::fileTransfer_ptr
-Engines_Container_i::getFileTransfer()
+Abstract_Engines_Container_i::getFileTransfer()
{
Engines::fileTransfer_var aFileTransfer
= Engines::fileTransfer::_duplicate(_fileTransfer);
//! Create a Salome file
//=============================================================================
Engines::Salome_file_ptr
-Engines_Container_i::createSalome_file(const char* origFileName)
+Abstract_Engines_Container_i::createSalome_file(const char* origFileName)
{
std::string origName(origFileName);
if (CORBA::is_nil(_Salome_file_map[origName]))
aSalome_file->setLocalFile(origFileName);
aSalome_file->recvFiles();
}
- catch (const SALOME::SALOME_Exception& e)
+ catch (const SALOME::SALOME_Exception& /*e*/) //!< TODO: unused variable
{
return Engines::Salome_file::_nil();
}
* \param localFile the local file
*/
//=============================================================================
-void Engines_Container_i::copyFile(Engines::Container_ptr container, const char* remoteFile, const char* localFile)
+void Abstract_Engines_Container_i::copyFile(Engines::Container_ptr container, const char* remoteFile, const char* localFile)
{
Engines::fileTransfer_var fileTransfer = container->getFileTransfer();
FILE* fp;
if ((fp = fopen(localFile,"wb")) == NULL)
- {
- INFOS("file " << localFile << " cannot be open for writing");
- return;
- }
+ {
+ INFOS("file " << localFile << " cannot be open for writing");
+ return;
+ }
CORBA::Long fileId = fileTransfer->open(remoteFile);
if (fileId > 0)
+ {
+ Engines::fileBlock* aBlock;
+ int toFollow = 1;
+ int ctr=0;
+ while (toFollow)
{
- Engines::fileBlock* aBlock;
- int toFollow = 1;
- int ctr=0;
- while (toFollow)
- {
- ctr++;
- SCRUTE(ctr);
- aBlock = fileTransfer->getBlock(fileId);
- toFollow = aBlock->length();
- SCRUTE(toFollow);
- CORBA::Octet *buf = aBlock->get_buffer();
- fwrite(buf, sizeof(CORBA::Octet), toFollow, fp);
- delete aBlock;
- }
- fclose(fp);
- MESSAGE("end of transfer");
- fileTransfer->close(fileId);
+ ctr++;
+ //SCRUTE(ctr);
+ aBlock = fileTransfer->getBlock(fileId);
+ toFollow = aBlock->length();
+ //SCRUTE(toFollow);
+ CORBA::Octet *buf = aBlock->get_buffer();
+ fwrite(buf, sizeof(CORBA::Octet), toFollow, fp);
+ delete aBlock;
}
+ fclose(fp);
+ MESSAGE("end of transfer");
+ fileTransfer->close(fileId);
+ }
else
- {
- INFOS("open reference file for copy impossible");
- }
+ {
+ INFOS("open reference file for copy impossible");
+ }
}
//=============================================================================
* \return the PyNode
*/
//=============================================================================
-Engines::PyNode_ptr Engines_Container_i::createPyNode(const char* nodeName, const char* code)
+Engines::PyNode_ptr Abstract_Engines_Container_i::createPyNode(const char* nodeName, const char* code)
{
- Engines::PyNode_var node= Engines::PyNode::_nil();
-
- PyGILState_STATE gstate = PyGILState_Ensure();
+ Engines::PyNode_var node= Engines::PyNode::_nil();
+ long ierr(-1);
+ std::string astr;
+ {
+ AutoGIL gstate;
PyObject *res = PyObject_CallMethod(_pyCont,
(char*)"create_pynode",
(char*)"ss",
nodeName,
code);
if(res==NULL)
- {
- //internal error
- PyErr_Print();
- PyGILState_Release(gstate);
- SALOME::ExceptionStruct es;
- es.type = SALOME::INTERNAL_ERROR;
- es.text = "can not create a python node";
- throw SALOME::SALOME_Exception(es);
- }
- long ierr=PyInt_AsLong(PyTuple_GetItem(res,0));
+ {
+ //internal error
+ PyErr_Print();
+ SALOME::ExceptionStruct es;
+ es.type = SALOME::INTERNAL_ERROR;
+ es.text = "can not create a python node";
+ throw SALOME::SALOME_Exception(es);
+ }
+ ierr=PyLong_AsLong(PyTuple_GetItem(res,0));
PyObject* result=PyTuple_GetItem(res,1);
- std::string astr=PyString_AsString(result);
+ astr = PyUnicode_AsUTF8(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);
- if(!CORBA::is_nil(_dftPyNode))
- _dftPyNode->UnRegister();
- _dftPyNode = node;
- if(!CORBA::is_nil(_dftPyNode))
- _dftPyNode->Register();
- return node._retn();
- }
+ }
+ if(ierr==0)
+ {
+ 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
- {
- SALOME::ExceptionStruct es;
- es.type = SALOME::INTERNAL_ERROR;
- es.text = astr.c_str();
- throw SALOME::SALOME_Exception(es);
- }
-
+ {
+ 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
+ {
+ SALOME::ExceptionStruct es;
+ es.type = SALOME::INTERNAL_ERROR;
+ es.text = astr.c_str();
+ throw SALOME::SALOME_Exception(es);
+ }
}
//=============================================================================
*
*/
//=============================================================================
-Engines::PyNode_ptr Engines_Container_i::getDefaultPyNode()
+Engines::PyNode_ptr Abstract_Engines_Container_i::getDefaultPyNode(const char *nodeName)
{
- if(!CORBA::is_nil(_dftPyNode))
- return Engines::PyNode::_duplicate(_dftPyNode);
- else
+ 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();
+ }
}
//=============================================================================
* \return the PyScriptNode
*/
//=============================================================================
-Engines::PyScriptNode_ptr Engines_Container_i::createPyScriptNode(const char* nodeName, const char* code)
+Engines::PyScriptNode_ptr Abstract_Engines_Container_i::createPyScriptNode(const char* nodeName, const char* code)
{
- Engines::PyScriptNode_var node= Engines::PyScriptNode::_nil();
-
- PyGILState_STATE gstate = PyGILState_Ensure();
+ Engines::PyScriptNode_var node= Engines::PyScriptNode::_nil();
+ long ierr(-1);
+ std::string astr;
+ {
+ AutoGIL gstate;
PyObject *res = PyObject_CallMethod(_pyCont,
(char*)"create_pyscriptnode",
(char*)"ss",
nodeName,
code);
if(res==NULL)
- {
- //internal error
- PyErr_Print();
- PyGILState_Release(gstate);
- SALOME::ExceptionStruct es;
- es.type = SALOME::INTERNAL_ERROR;
- es.text = "can not create a python node";
- throw SALOME::SALOME_Exception(es);
- }
- long ierr=PyInt_AsLong(PyTuple_GetItem(res,0));
+ {
+ //internal error
+ PyErr_Print();
+ SALOME::ExceptionStruct es;
+ es.type = SALOME::INTERNAL_ERROR;
+ es.text = "can not create a python node";
+ throw SALOME::SALOME_Exception(es);
+ }
+ ierr=PyLong_AsLong(PyTuple_GetItem(res,0));
PyObject* result=PyTuple_GetItem(res,1);
- std::string astr=PyString_AsString(result);
+ astr = PyUnicode_AsUTF8(result);
Py_DECREF(res);
- PyGILState_Release(gstate);
+ }
- if(ierr==0)
- {
- CORBA::Object_var obj = _orb->string_to_object(astr.c_str());
- node = Engines::PyScriptNode::_narrow(obj);
- if(!CORBA::is_nil(_dftPyScriptNode))
- _dftPyScriptNode->UnRegister();
- _dftPyScriptNode = node;
- if(!CORBA::is_nil(_dftPyScriptNode))
- _dftPyScriptNode->Register();
- return node._retn();
- }
+ if(ierr==0)
+ {
+ 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
- {
- SALOME::ExceptionStruct es;
- es.type = SALOME::INTERNAL_ERROR;
- es.text = astr.c_str();
- throw SALOME::SALOME_Exception(es);
- }
+ {
+ Engines::PyScriptNode_var oldNode((*it).second);
+ if(!CORBA::is_nil(oldNode))
+ oldNode->UnRegister();
+ (*it).second=node;
+ }
+ return node._retn();
+ }
+ else
+ {
+ SALOME::ExceptionStruct es;
+ es.type = SALOME::INTERNAL_ERROR;
+ es.text = astr.c_str();
+ throw SALOME::SALOME_Exception(es);
+ }
+}
+
+void Abstract_Engines_Container_i::removePyScriptNode(const char *nodeName)
+{
+ std::map<std::string,Engines::PyScriptNode_var>::iterator it(_dftPyScriptNode.find(nodeName));
+ if(it==_dftPyScriptNode.end())
+ {
+ std::ostringstream oss; oss << "Engines_Container_i::removePyScriptNode : node \"" << nodeName << "\" is not map !";
+ SALOME::ExceptionStruct es;
+ es.type = SALOME::INTERNAL_ERROR;
+ es.text = oss.str().c_str();
+ throw SALOME::SALOME_Exception(es);
+ }
+ (*it).second->UnRegister();
+ _dftPyScriptNode.erase(it);
+}
+
+void Abstract_Engines_Container_i::cleanAllPyScripts()
+{
+ 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();
+ }
+ _dftPyNode.clear();
+ 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();
+ }
+ _dftPyScriptNode.clear();
}
//=============================================================================
*
*/
//=============================================================================
-Engines::PyScriptNode_ptr Engines_Container_i::getDefaultPyScriptNode()
+Engines::PyScriptNode_ptr Abstract_Engines_Container_i::getDefaultPyScriptNode(const char *nodeName)
{
- if(!CORBA::is_nil(_dftPyScriptNode))
- return Engines::PyScriptNode::_duplicate(_dftPyScriptNode);
- else
+ 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();
+ }
}
//=============================================================================
return found;
}
-void Engines_Container_i::registerTemporaryFile( const std::string& fileName )
+void Abstract_Engines_Container_i::registerTemporaryFile( const std::string& fileName )
{
_tmp_files.remove( fileName );
_tmp_files.push_back( fileName );
}
-void Engines_Container_i::unregisterTemporaryFile( const std::string& fileName )
+void Abstract_Engines_Container_i::unregisterTemporaryFile( const std::string& fileName )
{
_tmp_files.remove( fileName );
}
-void Engines_Container_i::clearTemporaryFiles()
+void Abstract_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 /P";
+#if defined(WIN32) && defined(UNICODE)
+ std::wstring aFile = Kernel_Utils::utf8_decode_s(*it);
+ std::wstring command = (GetFileAttributes(aFile.c_str()) == FILE_ATTRIBUTE_DIRECTORY) ? L"rd /Q \"" : L"del /F /Q \"";
+ command += aFile;
+ command += L"\" 2>NUL";
+ _wsystem(command.c_str());
+#else
+#if defined(WIN32)
+ std::string aFile = *it;
+ std::string command = (GetFileAttributes(aFile.c_str()) == FILE_ATTRIBUTE_DIRECTORY) ? "rd /Q \"" : "del /F /Q \"";
+ command += aFile;
+ command += "\" 2>NUL";
#else
- std::string command = "rm -rf ";
+ std::string command = "rm -rf ";
+ command += *it;
+#endif
+ system(command.c_str());
#endif
- command += *it;
- system( command.c_str() );
}
_tmp_files.clear();
}
+
+static Engines_Container_SSL_i *_container_singleton_ssl = nullptr;
+
+static Engines::Container_var _container_ref_singleton_ssl;
+
+Engines_Container_SSL_i *KERNEL::getContainerSA()
+{
+ if(!_container_singleton_ssl)
+ {
+ CORBA::ORB_var orb = KERNEL::GetRefToORB();
+ CORBA::Object_var obj = orb->resolve_initial_references("RootPOA");
+ PortableServer::POA_var poa = PortableServer::POA::_narrow(obj);
+ PortableServer::POAManager_var pman = poa->the_POAManager();
+ CORBA::PolicyList policies;
+ policies.length(0);
+ //
+ char *argv[4] = {"Container","FactoryServer","toto",nullptr};
+ SALOME_Fake_NamingService ns;
+ _container_singleton_ssl = new Engines_Container_SSL_i(orb,poa,"FactoryServer",2,argv,&ns,false);
+ PortableServer::ObjectId * cont_id = _container_singleton_ssl->getCORBAId();
+ //
+ CORBA::Object_var zeRef = poa->id_to_reference(*cont_id);
+ _container_ref_singleton_ssl = Engines::Container::_narrow(zeRef);
+ }
+ return _container_singleton_ssl;
+}
+
+Engines::Container_var KERNEL::getContainerRefSA()
+{
+ getContainerSA();
+ return _container_ref_singleton_ssl;
+}