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