Salome HOME
Merge branch 'master' of https://codev-tuleap.cea.fr/plugins/git/salome/gui
[modules/gui.git] / src / Session / Session_ServerThread.cxx
1 // Copyright (C) 2007-2016  CEA/DEN, EDF R&D, OPEN CASCADE
2 //
3 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
5 //
6 // This library is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU Lesser General Public
8 // License as published by the Free Software Foundation; either
9 // version 2.1 of the License, or (at your option) any later version.
10 //
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 // Lesser General Public License for more details.
15 //
16 // You should have received a copy of the GNU Lesser General Public
17 // License along with this library; if not, write to the Free Software
18 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
19 //
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
21 //
22
23 //  SALOME Session : implementation of Session_ServerThread.cxx
24 //  File   : Session_ServerThread.cxx
25 //  Author : Paul RASCLE, EDF
26
27 #include "Session_ServerThread.hxx"
28
29 #include <SALOME_NamingService.hxx>
30 #include <SALOME_Container_i.hxx>
31 #include <SALOME_Launcher.hxx>
32 #include <SALOMEDSClient_ClientFactory.hxx>
33 #include <SALOME_ModuleCatalog_impl.hxx>
34 #include <RegistryService.hxx>
35
36 #include "Session_Session_i.hxx"
37
38 #include <Utils_ORB_INIT.hxx>
39 #include <Utils_SINGLETON.hxx>
40 #include <Utils_SALOME_Exception.hxx>
41 #include <Basics_Utils.hxx>
42 #include <NamingService_WaitForServerReadiness.hxx>
43 #include <utilities.h>
44
45 #include <cstdlib>
46 #include <ctime>
47
48 #include <QMutex>
49 #include <QWaitCondition>
50
51 const int Session_ServerThread::NB_SRV_TYP = 6;
52 const char* Session_ServerThread::_serverTypes[NB_SRV_TYP] = {"Container",
53                                                               "ModuleCatalog",
54                                                               "Registry",
55                                                               "SALOMEDS",
56                                                               "Session",
57                                                               "ContainerManager"};
58
59 /*! 
60   default constructor not for use
61 */
62 Session_ServerThread::Session_ServerThread()
63 {
64   ASSERT(0); // must not be called
65 }
66
67 /*! 
68   constructor
69 */
70 Session_ServerThread::Session_ServerThread(int argc,
71                                            char ** argv, 
72                                            CORBA::ORB_ptr orb, 
73                                            PortableServer::POA_ptr poa)
74 {
75   //MESSAGE("Session_ServerThread Constructor " << argv[0]);
76   _argc = argc;
77   _argv = new char*[ _argc + 1 ];
78   _argv[_argc] = 0;
79   for (int i = 0; i < _argc; i++ )
80     _argv[i] = strdup( argv[i] );
81
82   _orb = CORBA::ORB::_duplicate(orb);
83   _root_poa = PortableServer::POA::_duplicate(poa);
84   _servType =-1;
85   _NS = new SALOME_NamingService(_orb); // one instance per server to limit
86                                         // multi thread coherence problems
87   _container = 0;                       // embedded container
88 }
89
90 /*! 
91   destructor 
92 */
93 Session_ServerThread::~Session_ServerThread()
94 {
95   //MESSAGE("~Session_ServerThread "<< _argv[0]);
96   delete _NS;
97   for (int i = 0; i <_argc ; i++ )
98     free( _argv[i] );
99   delete[] _argv;
100 }
101
102 /*! 
103   run the thread : activate one servant, the servant type is given by
104   argument _argv[0]
105 */
106 void Session_ServerThread::Init()
107 {
108   MESSAGE("Session_ServerThread::Init "<< _argv[0]); 
109
110   int i;
111   for (i=0; i<_argc; i++) SCRUTE(_argv[i]);
112
113   for (i=0; i<NB_SRV_TYP; i++) {
114     if (strcmp(_argv[0],_serverTypes[i])==0) {
115       _servType = i;
116       MESSAGE("Server Thread type : "<<_serverTypes[i]);
117       switch (_servType) {
118       case 0:  // Container
119         {
120           NamingService_WaitForServerReadiness(_NS,"/Registry");
121           NamingService_WaitForServerReadiness(_NS,"/ContainerManager");
122           ActivateContainer(_argc, _argv);
123           break;
124         }
125       case 1:  // ModuleCatalog
126         {
127           NamingService_WaitForServerReadiness(_NS,"/Registry");
128           ActivateModuleCatalog(_argc, _argv);
129           break;
130         }
131       case 2:  // Registry
132         {
133           NamingService_WaitForServerReadiness(_NS,"");
134           ActivateRegistry(_argc, _argv);
135           break;
136         }
137       case 3:  // SALOMEDS
138         {
139           NamingService_WaitForServerReadiness(_NS,"/Kernel/ModulCatalog");
140           ActivateSALOMEDS(_argc, _argv);
141           break;
142         }
143       case 4:  // Session
144         {
145           NamingService_WaitForServerReadiness(_NS,"/myStudyManager");
146           std::string containerName = "/Containers/";
147           containerName = containerName + Kernel_Utils::GetHostname();
148           containerName = containerName + "/FactoryServer";
149           NamingService_WaitForServerReadiness(_NS,containerName);
150           ActivateSession(_argc, _argv);
151           break;
152         }
153       case 5: // Container Manager
154         {
155           NamingService_WaitForServerReadiness(_NS,"");
156           ActivateContainerManager(_argc, _argv);
157           break;
158         }
159       default:
160         {
161           ASSERT(0);
162           break;
163         }
164       }
165     }
166   }
167 }
168
169 void Session_ServerThread::Shutdown()
170 {
171   if ( _container ) _container->Shutdown();
172 }
173
174 void Session_ServerThread::ActivateModuleCatalog(int argc,
175                                                  char ** argv)
176 {
177   try {
178     MESSAGE("ModuleCatalog thread started");
179     // allocation on heap to allow destruction by POA
180     
181     SALOME_ModuleCatalogImpl* Catalogue_i
182       = new SALOME_ModuleCatalogImpl(argc, argv);
183     
184     // Tell the POA that the objects are ready to accept requests.
185     
186     PortableServer::ObjectId_var id = _root_poa->activate_object (Catalogue_i);
187     Catalogue_i->_remove_ref();
188     
189     CORBA::Object_var myCata = Catalogue_i->_this();
190     _NS->Register(myCata ,"/Kernel/ModulCatalog");
191   }
192   catch(CORBA::SystemException&) {
193     INFOS( "Caught CORBA::SystemException." );
194   }
195   catch(CORBA::Exception&) {
196     INFOS( "Caught CORBA::Exception." );
197   }
198   catch(omniORB::fatalException& fe) {
199     INFOS( "Caught omniORB::fatalException:" );
200     INFOS( "  file: " << fe.file() );
201     INFOS( "  line: " << fe.line() );
202     INFOS( "  mesg: " << fe.errmsg() );
203   }
204   catch(...) {
205     INFOS( "Caught unknown exception." );
206   }
207 }
208
209 void Session_ServerThread::ActivateSALOMEDS(int argc,
210                                             char ** argv)
211 {
212   try {
213     MESSAGE("SALOMEDS thread started");
214     // We allocate the objects on the heap.  Since these are reference
215     // counted objects, they will be deleted by the POA when they are no
216     // longer needed.    
217     
218     ClientFactory::createStudyManager(_orb,_root_poa);
219   }
220   catch(CORBA::SystemException&) {
221     INFOS( "Caught CORBA::SystemException." );
222   }
223   catch(CORBA::Exception&) {
224     INFOS( "Caught CORBA::Exception." );
225   }
226   catch(omniORB::fatalException& fe) {
227     INFOS( "Caught omniORB::fatalException:" );
228     INFOS( "  file: " << fe.file() );
229     INFOS( "  line: " << fe.line() );
230     INFOS( "  mesg: " << fe.errmsg() );
231   }
232   catch(...) {
233     INFOS( "Caught unknown exception." );
234   }
235 }
236
237 void Session_ServerThread::ActivateRegistry(int argc,
238                                             char ** argv)
239 {
240   MESSAGE("Registry thread started");
241   SCRUTE(argc); 
242   if ( argc<3 ) {
243     INFOS("you must provide the Salome session name when you call SALOME_Registry_Server");
244     throw CommException("you must provide the Salome session name when you call SALOME_Registry_Server");
245   }
246   const char *ptrSessionName=0;
247
248   int k=0 ;
249   for ( k=1 ; k<argc ; k++ ) {
250     if ( strcmp(argv[k],"--salome_session")==0 ) {
251       ptrSessionName=argv[k+1];
252       break;
253     }
254   }
255   ASSERT(ptrSessionName) ;
256   ASSERT(strlen( ptrSessionName )>0);
257   const char *registryName = "Registry";
258   Registry::Components_var varComponents;
259   try {
260     RegistryService *ptrRegistry = new RegistryService;
261     ptrRegistry->SessionName( ptrSessionName );
262     ptrRegistry->SetOrb(_orb);
263     //
264     CORBA::PolicyList policies;
265     policies.length(1);
266     PortableServer::ThreadPolicy_var threadPol(_root_poa->create_thread_policy(PortableServer::SINGLE_THREAD_MODEL));
267     policies[0]=PortableServer::ThreadPolicy::_duplicate(threadPol);
268     PortableServer::POAManager_var manager = _root_poa->the_POAManager();
269     PortableServer::POA_var poa2(_root_poa->create_POA("SingleThreadPOA4RegistryEmbedded",manager,policies));
270     threadPol->destroy();
271     //
272     PortableServer::ObjectId_var id(poa2->activate_object(ptrRegistry));
273     CORBA::Object_var pipo=poa2->id_to_reference(id);
274     varComponents = Registry::Components::_narrow(pipo) ;
275     ptrRegistry->_remove_ref(); //let poa manage registryservice deletion
276     
277     try {
278       CORBA::Object_var pipo = _NS->Resolve( registryName );
279       if (CORBA::is_nil(pipo) )  throw ServiceUnreachable();
280       INFOS("RegistryService servant already existing" );
281       ASSERT(0);
282     }
283     catch( const ServiceUnreachable &/*ex*/ ) {
284     }
285     catch( const CORBA::Exception &/*exx*/ ) {
286     }
287     std::string absoluteName = std::string("/") + registryName;
288     _NS->Register( varComponents , absoluteName.c_str() );
289   }
290   catch( const SALOME_Exception &ex ) {
291     INFOS( "Communication Error : " << ex.what() );
292     ASSERT(0);
293   }
294 }
295
296 void Session_ServerThread::ActivateContainerManager(int argc,
297                                              char ** argv)
298 {
299   try {
300     PortableServer::POA_var root_poa=PortableServer::POA::_the_root_poa();
301     std::cout << "Activate SalomeLauncher ......!!!! " << std::endl;
302     new SALOME_Launcher(_orb,root_poa);
303   }
304   catch(CORBA::SystemException&) {
305     INFOS("Caught CORBA::SystemException.");
306   }
307   catch(PortableServer::POA::WrongPolicy&) {
308     INFOS("Caught CORBA::WrongPolicyException.");
309   }
310   catch(PortableServer::POA::ServantAlreadyActive&) {
311     INFOS("Caught CORBA::ServantAlreadyActiveException");
312   }
313   catch(CORBA::Exception&) {
314     INFOS("Caught CORBA::Exception.");
315   }
316   catch(...) {
317     INFOS("Caught unknown exception.");
318   }
319 }
320
321 void Session_ServerThread::ActivateContainer(int argc,
322                                              char ** argv)
323 {
324   try {
325     MESSAGE("Container thread started");
326     
327     // get or create the child POA
328     
329     PortableServer::POA_var factory_poa;
330     try {
331       factory_poa = _root_poa->find_POA("factory_poa",0);
332       // 0 = no activation (already done if exists)
333     }
334     catch (PortableServer::POA::AdapterNonExistent&) {
335       MESSAGE("factory_poa does not exists, create...");
336       // define policy objects     
337       PortableServer::ImplicitActivationPolicy_var implicitActivation =
338         _root_poa->create_implicit_activation_policy(PortableServer::NO_IMPLICIT_ACTIVATION);
339       // default = NO_IMPLICIT_ACTIVATION
340       PortableServer::ThreadPolicy_var threadPolicy =
341         _root_poa->create_thread_policy(PortableServer::ORB_CTRL_MODEL);
342       // default = ORB_CTRL_MODEL, other choice SINGLE_THREAD_MODEL
343       
344       // create policy list
345       CORBA::PolicyList policyList;
346       policyList.length(2);
347       policyList[0] = PortableServer::ImplicitActivationPolicy::
348         _duplicate(implicitActivation);
349       policyList[1] = PortableServer::ThreadPolicy::
350         _duplicate(threadPolicy);
351       
352       PortableServer::POAManager_var nil_mgr
353         = PortableServer::POAManager::_nil();
354       factory_poa = _root_poa->create_POA("factory_poa",
355                                           nil_mgr,
356                                           policyList);
357       //with nil_mgr instead of pman,
358       //a new POA manager is created with the new POA
359       
360       // destroy policy objects
361       implicitActivation->destroy();
362       threadPolicy->destroy();
363       
364       // obtain the factory poa manager
365       PortableServer::POAManager_var pmanfac = factory_poa->the_POAManager();
366       pmanfac->activate();
367       MESSAGE("pmanfac->activate()");
368     }
369     
370     char *containerName = (char*)"";
371     if (argc >1) {
372       containerName = argv[1];
373     }
374     
375     _container = new Engines_Container_i(_orb, _root_poa, containerName , argc , argv , true , false);
376   }
377   catch(CORBA::SystemException&) {
378     INFOS("Caught CORBA::SystemException.");
379   }
380   catch(PortableServer::POA::WrongPolicy&) {
381     INFOS("Caught CORBA::WrongPolicyException.");
382   }
383   catch(PortableServer::POA::ServantAlreadyActive&) {
384     INFOS("Caught CORBA::ServantAlreadyActiveException");
385   }
386   catch(CORBA::Exception&) {
387     INFOS("Caught CORBA::Exception.");
388   }
389   catch(...) {
390     INFOS("Caught unknown exception.");
391   }
392 }
393
394 void Session_ServerThread::ActivateSession(int argc,
395                                            char ** argv)
396 {
397   MESSAGE("Session_ServerThread::ActivateSession() not implemented!");
398 }
399
400 /*! 
401   constructor 
402 */
403 Session_SessionThread::Session_SessionThread(int argc,
404                                              char** argv, 
405                                              CORBA::ORB_ptr orb, 
406                                              PortableServer::POA_ptr poa,
407                                              QMutex* GUIMutex,
408                                              QWaitCondition* GUILauncher)
409 : Session_ServerThread(argc, argv, orb, poa),
410   _GUIMutex( GUIMutex ),
411   _GUILauncher( GUILauncher )
412 {
413 }
414
415 /*! 
416   destructor 
417 */
418 Session_SessionThread::~Session_SessionThread()
419 {
420 }
421
422 void Session_SessionThread::ActivateSession(int argc,
423                                             char ** argv)
424 {
425   try {
426     MESSAGE("Session thread started");
427     SALOME_Session_i * mySALOME_Session
428       = new SALOME_Session_i(argc, argv, _orb, _root_poa, _GUIMutex, _GUILauncher) ;
429     PortableServer::ObjectId_var mySALOME_Sessionid
430       = _root_poa->activate_object(mySALOME_Session);
431     MESSAGE("poa->activate_object(mySALOME_Session)");
432     
433     CORBA::Object_var obj = mySALOME_Session->_this();
434     CORBA::String_var sior(_orb->object_to_string(obj));
435     mySALOME_Session->_remove_ref();
436     
437     mySALOME_Session->NSregister();
438   }
439   catch (CORBA::SystemException&) {
440     INFOS("Caught CORBA::SystemException.");
441   }
442   catch (CORBA::Exception&) {
443     INFOS("Caught CORBA::Exception.");
444   }
445   catch (...) {
446     INFOS("Caught unknown exception.");
447   }
448 }