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