int _ArgC ;
char ** _ArgV ;
-
-// Containers with name FactoryServer are started via rsh in LifeCycleCORBA
-// Other Containers are started via start_impl of FactoryServer
-
extern "C" {void ActSigIntHandler() ; }
#ifndef WIN32
extern "C" {void SigIntHandler(int, siginfo_t *, void *) ; }
map<std::string, void *> Engines_Container_i::_toRemove_map;
omni_mutex Engines_Container_i::_numInstanceMutex ;
+static PyObject* _pyCont;
+
+int checkifexecutable(const std::string&);
+int findpathof(std::string&, const std::string&);
+
+/*! \class Engines_Container_i
+ * \brief C++ implementation of Engines::Container interface
+ *
+ */
+
+
//=============================================================================
/*!
* Default constructor, not for use
//=============================================================================
Engines_Container_i::Engines_Container_i () :
-_numInstance(0)
+_numInstance(0),_id(0),_NS(0)
{
}
bool activAndRegist,
bool isServantAloneInProcess
) :
-_numInstance(0),_isServantAloneInProcess(isServantAloneInProcess)
+ _numInstance(0),_isServantAloneInProcess(isServantAloneInProcess),_id(0),_NS(0)
{
_pid = (long)getpid();
if (!_isSupervContainer)
{
-#ifdef WIN32
-
- PyEval_AcquireLock();
- PyThreadState *myTstate = PyThreadState_New(KERNEL_PYTHON::_interp);
- PyThreadState *myoldTstate = PyThreadState_Swap(myTstate);
-#else
- Py_ACQUIRE_NEW_THREAD;
-#endif
+ PyGILState_STATE gstate = PyGILState_Ensure();
#ifdef WIN32
// mpv: this is temporary solution: there is a unregular crash if not
#endif
PyRun_SimpleString("import SALOME_Container\n");
PyRun_SimpleString((char*)myCommand.c_str());
- Py_RELEASE_NEW_THREAD;
+ PyObject *mainmod = PyImport_AddModule("__main__");
+ PyObject *globals = PyModule_GetDict(mainmod);
+ _pyCont = PyDict_GetItemString(globals, "pyCont");
+
+ PyGILState_Release(gstate);
}
fileTransfer_i* aFileTransfer = new fileTransfer_i();
Engines_Container_i::~Engines_Container_i()
{
MESSAGE("Container_i::~Container_i()");
- delete _id;
+ if(_id)
+ delete _id;
if(_NS)
delete _NS;
}
//=============================================================================
+//! Get container name
/*!
* CORBA attribute: Container name (see constructor)
*/
}
//=============================================================================
+//! Get container working directory
/*!
* CORBA attribute: Container working directory
*/
}
//=============================================================================
+//! Get container log file name
/*!
* CORBA attribute: Container log file name
*/
return CORBA::string_dup(_logfilename.c_str()) ;
}
+//! Set container log file name
void Engines_Container_i::logfilename(const char* name)
{
_logfilename=name;
}
//=============================================================================
+//! Get container host name
/*!
* CORBA method: Get the hostName of the Container (without domain extensions)
*/
}
//=============================================================================
+//! Get container PID
/*!
* CORBA method: Get the PID (process identification) of the Container
*/
}
//=============================================================================
+//! Ping the servant to check it is still alive
/*!
* CORBA method: check if servant is still alive
*/
}
//=============================================================================
+//! Shutdown the container
/*!
* CORBA method, oneway: Server shutdown.
* - Container name removed from naming service,
// ignore this entry and continue
}
}
+ _listInstances_map.clear();
_NS->Destroy_FullDirectory(_containerName.c_str());
_NS->Destroy_Name(_containerName.c_str());
- //_remove_ref();
- //_poa->deactivate_object(*_id);
if(_isServantAloneInProcess)
{
MESSAGE("Effective Shutdown of container Begins...");
{
string path( getenv("PATH") );
if ( path.size() == 0 )
- return 0;
-
+ return 0;
+
char path_spr =
#ifdef WIN32
';';
//=============================================================================
+//! load a new component class
/*!
* CORBA method: load a new component class (Python or C++ implementation)
* \param componentName like COMPONENT
return true;
}
+ std::string retso="";
#ifndef WIN32
void* handle;
handle = dlopen( impl_name.c_str() , RTLD_LAZY ) ;
+ if ( !handle )retso=dlerror();
#else
HINSTANCE handle;
handle = LoadLibrary( impl_name.c_str() );
// --- try import Python component
INFOS("try import Python component "<<componentName);
+ std::string retpy;
if (_isSupervContainer)
{
INFOS("Supervision Container does not support Python Component Engines");
}
else
{
- Py_ACQUIRE_NEW_THREAD;
- PyObject *mainmod = PyImport_AddModule("__main__");
- PyObject *globals = PyModule_GetDict(mainmod);
- PyObject *pyCont = PyDict_GetItemString(globals, "pyCont");
- PyObject *result = PyObject_CallMethod(pyCont,
+ PyGILState_STATE gstate = PyGILState_Ensure();
+ PyObject *result = PyObject_CallMethod(_pyCont,
(char*)"import_component",
(char*)"s",componentName);
- int ret= PyInt_AsLong(result);
+
+ retpy=PyString_AsString(result);
Py_XDECREF(result);
- SCRUTE(ret);
- Py_RELEASE_NEW_THREAD;
+ SCRUTE(retpy);
+ PyGILState_Release(gstate);
- if (ret) // import possible: Python component
+ if (retpy=="") // import possible: Python component
{
_numInstanceMutex.lock() ; // lock to be alone (stl container write)
- _library_map[aCompName] = (void *)pyCont; // any non O value OK
+ _library_map[aCompName] = (void *)_pyCont; // any non O value OK
_numInstanceMutex.unlock() ;
MESSAGE("import Python: "<<aCompName<<" OK");
return true;
INFOS( "Impossible to load component: " << componentName );
INFOS( "Can't load shared library: " << impl_name );
+ std::cerr << retso << std::endl;
INFOS( "Can't import Python module: " << componentName );
+ std::cerr << retpy << std::endl;
INFOS( "Can't execute program: " << executable );
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.
string component_registerName =
_containerName + "/" + instanceName;
- Py_ACQUIRE_NEW_THREAD;
- PyObject *mainmod = PyImport_AddModule("__main__");
- PyObject *globals = PyModule_GetDict(mainmod);
- PyObject *pyCont = PyDict_GetItemString(globals, "pyCont");
- PyObject *result = PyObject_CallMethod(pyCont,
+ PyGILState_STATE gstate = PyGILState_Ensure();
+ PyObject *result = PyObject_CallMethod(_pyCont,
(char*)"create_component_instance",
(char*)"ssl",
aCompName.c_str(),
string iors = PyString_AsString(result);
Py_DECREF(result);
SCRUTE(iors);
- Py_RELEASE_NEW_THREAD;
+ PyGILState_Release(gstate);
if( iors!="" )
{
}
//=============================================================================
+//! Find an existing (in the container) component instance
/*!
* CORBA method: Finds a servant instance of a component
* \param registeredName Name of the component in Registry or Name Service,
}
//=============================================================================
+//! Find or create a new component instance
/*!
* CORBA method: find or create an instance of the component (servant),
* load a new component class (dynamic library) if required,
+*
* ---- FOR COMPATIBILITY WITH 2.2 ----
+*
* ---- USE ONLY FOR MULTISTUDY INSTANCES ! --------
+*
* The servant registers itself to naming service and Registry.
* \param genericRegisterName Name of the component to register
* in Registry & Name Service
//=============================================================================
+//! Remove the component instance from container
/*!
* CORBA method: Stops the component servant, and deletes all related objects
* \param component_i Component to be removed
}
//=============================================================================
+//! Unload component libraries from the container
/*!
* CORBA method: Discharges unused libraries from the container.
*/
}
//=============================================================================
+//! Kill the container
/*!
* CORBA method: Kill the container process with exit(0).
* To remove : never returns !
}
//=============================================================================
+//! Get or create a file reference object associated to a local file (to transfer it)
/*!
* CORBA method: get or create a fileRef object associated to a local file
* (a file on the computer on which runs the container server), which stores
}
//=============================================================================
+//! Get a fileTransfer reference
/*!
* CORBA method:
* \return a reference to the fileTransfer object
}
+//! Create a Salome file
Engines::Salome_file_ptr
Engines_Container_i::createSalome_file(const char* origFileName)
{
return theSalome_file;
}
//=============================================================================
+//! Finds an already existing component instance or create a new instance
/*!
* C++ method: Finds an already existing servant instance of a component, or
* create an instance.
* \return a loaded component
*
* example with names:
-* aGenRegisterName = COMPONENT (= first argument)
-* impl_name = libCOMPONENTEngine.so (= second argument)
-* _containerName = /Containers/cli76ce/FactoryServer
-* factoryName = COMPONENTEngine_factory
-* component_registerBase = /Containers/cli76ce/FactoryServer/COMPONENT
-*
-* instanceName = COMPONENT_inst_1
-* component_registerName = /Containers/cli76ce/FactoryServer/COMPONENT_inst_1
+* - aGenRegisterName = COMPONENT (= first argument)
+* - impl_name = libCOMPONENTEngine.so (= second argument)
+* - _containerName = /Containers/cli76ce/FactoryServer
+* - factoryName = COMPONENTEngine_factory
+* - component_registerBase = /Containers/cli76ce/FactoryServer/COMPONENT
+* - instanceName = COMPONENT_inst_1
+* - component_registerName = /Containers/cli76ce/FactoryServer/COMPONENT_inst_1
*/
//=============================================================================
Engines::Component_ptr
-Engines_Container_i::find_or_create_instance(string genericRegisterName,
- string componentLibraryName)
+Engines_Container_i::find_or_create_instance(std::string genericRegisterName,
+ std::string componentLibraryName)
{
string aGenRegisterName = genericRegisterName;
string impl_name = componentLibraryName;
}
//=============================================================================
+//! Create a new component instance
/*!
* C++ method: create a servant instance of a component.
* \param genericRegisterName Name of the component instance to register
* \return a loaded component
*
* example with names:
-* aGenRegisterName = COMPONENT (= first argument)
-* _containerName = /Containers/cli76ce/FactoryServer
-* factoryName = COMPONENTEngine_factory
-* component_registerBase = /Containers/cli76ce/FactoryServer/COMPONENT
-* instanceName = COMPONENT_inst_1
-* component_registerName = /Containers/cli76ce/FactoryServer/COMPONENT_inst_1
+* - aGenRegisterName = COMPONENT (= first argument)
+* - _containerName = /Containers/cli76ce/FactoryServer
+* - factoryName = COMPONENTEngine_factory
+* - component_registerBase = /Containers/cli76ce/FactoryServer/COMPONENT
+* - instanceName = COMPONENT_inst_1
+* - component_registerName = /Containers/cli76ce/FactoryServer/COMPONENT_inst_1
*/
//=============================================================================
Engines::Component_ptr
-Engines_Container_i::createInstance(string genericRegisterName,
+Engines_Container_i::createInstance(std::string genericRegisterName,
void *handle,
int studyId)
{
Engines_Component_i *servant =
dynamic_cast<Engines_Component_i*>(_poa->reference_to_servant(iobject));
ASSERT(servant);
- //SCRUTE(servant->pd_refCount);
- servant->_remove_ref(); // compensate previous id_to_reference
- //SCRUTE(servant->pd_refCount);
+ //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]);
- //SCRUTE(servant->pd_refCount);
-#if defined(_DEBUG_) || defined(_DEBUG)
- bool ret_studyId = servant->setStudyId(studyId);
- ASSERT(ret_studyId);
-#else
servant->setStudyId(studyId);
-#endif
+ 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)
}
//=============================================================================
+//! Decrement component instance reference count
/*!
*
*/
//=============================================================================
-void Engines_Container_i::decInstanceCnt(string genericRegisterName)
+void Engines_Container_i::decInstanceCnt(std::string genericRegisterName)
{
if(_cntInstances_map.count(genericRegisterName)==0)
return;
}
//=============================================================================
+//! Indicate if container is a python one
/*!
* Retrieves only with container naming convention if it is a python container
*/
#ifndef WIN32
struct sigaction SigIntAct ;
SigIntAct.sa_sigaction = &SigIntHandler ;
+ sigemptyset(&SigIntAct.sa_mask);
SigIntAct.sa_flags = SA_SIGINFO ;
#endif
}
}
#endif
+
+/*! \brief copy a file from a remote host (container) to the local host
+ * \param container the remote container
+ * \param remoteFile the file to copy locally from the remote host into localFile
+ * \param localFile the local file
+ */
+void 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;
+ }
+
+ CORBA::Long fileId = fileTransfer->open(remoteFile);
+ if (fileId > 0)
+ {
+ 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);
+ }
+ else
+ {
+ INFOS("open reference file for copy impossible");
+ }
+}
+
+/*! \brief create a PyNode object to execute remote python code
+ * \param nodeName the name of the node
+ * \param code the python code to load
+ * \return the PyNode
+ */
+Engines::PyNode_ptr Engines_Container_i::createPyNode(const char* nodeName, const char* code)
+{
+ Engines::PyNode_var node= Engines::PyNode::_nil();
+
+ PyGILState_STATE gstate = PyGILState_Ensure();
+ 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));
+ PyObject* result=PyTuple_GetItem(res,1);
+ 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);
+ return node._retn();
+ }
+ else
+ {
+ SALOME::ExceptionStruct es;
+ es.type = SALOME::INTERNAL_ERROR;
+ es.text = astr.c_str();
+ throw SALOME::SALOME_Exception(es);
+ }
+
+}