Salome HOME
Updated copyright comment
[modules/gui.git] / src / Session / Session_ServerThread.cxx
1 // Copyright (C) 2007-2024  CEA, EDF, 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 #include "Session_Promises.hxx"
29
30 #include <SALOME_NamingService.hxx>
31 #include <SALOME_Container_i.hxx>
32 #include <SALOME_Launcher.hxx>
33 #include <SALOME_ModuleCatalog_impl.hxx>
34 #include <RegistryService.hxx>
35
36 #include "Session_Session_i.hxx"
37
38 #include <Utils_CommException.hxx>
39 #include <Basics_Utils.hxx>
40 #include <NamingService_WaitForServerReadiness.hxx>
41 #include <utilities.h>
42
43 #include <cstdlib>
44 #include <ctime>
45
46 #include <QMutex>
47 #include <QWaitCondition>
48
49 template<class MY_NS>
50 const int Session_ServerThread<MY_NS>::NB_SRV_TYP = 6;
51
52 template<class MY_NS>
53 const char* Session_ServerThread<MY_NS>::_serverTypes[NB_SRV_TYP] = {"Container",
54                                                                       "ModuleCatalog",
55                                                                       "Registry",
56                                                                       "SALOMEDS",
57                                                                       "Session",
58                                                                       "ContainerManager"};
59
60 /*! 
61   default constructor not for use
62 */
63 template<class MY_NS>
64 Session_ServerThread<MY_NS>::Session_ServerThread()
65 {
66   ASSERT(0); // must not be called
67 }
68
69 /*! 
70   constructor
71 */
72 template<class MY_NS>
73 Session_ServerThread<MY_NS>::Session_ServerThread(int argc,
74                                            char ** argv, 
75                                            CORBA::ORB_ptr orb, 
76                                            PortableServer::POA_ptr poa)
77 {
78   //MESSAGE("Session_ServerThread Constructor " << argv[0]);
79   _argc = argc;
80   _argv = new char*[ _argc + 1 ];
81   _argv[_argc] = 0;
82   for (int i = 0; i < _argc; i++ )
83     _argv[i] = strdup( argv[i] );
84
85   _orb = CORBA::ORB::_duplicate(orb);
86   _root_poa = PortableServer::POA::_duplicate(poa);
87   _servType =-1;
88   _NS.reset( new MY_NS(_orb) ); // one instance per server to limit
89                                                // multi thread coherence problems
90   _container = nullptr;                        // embedded container
91 }
92
93 /*! 
94   destructor 
95 */
96 template<class MY_NS>
97 Session_ServerThread<MY_NS>::~Session_ServerThread()
98 {
99   for (int i = 0; i <_argc ; i++ )
100     free( _argv[i] );
101   delete[] _argv;
102 }
103
104 /*! 
105   run the thread : activate one servant, the servant type is given by
106   argument _argv[0]
107 */
108 template<class MY_NS>
109 void Session_ServerThread<MY_NS>::Init()
110 {
111   MESSAGE("Session_ServerThread::Init "<< _argv[0]); 
112
113   int i;
114   for (i=0; i<_argc; i++) SCRUTE(_argv[i]);
115
116   for (i=0; i<NB_SRV_TYP; i++) {
117     if (strcmp(_argv[0],_serverTypes[i])==0) {
118       _servType = i;
119       MESSAGE("Server Thread type : "<<_serverTypes[i]);
120       switch (_servType) {
121       case 0:  // Container
122         {
123           NamingService_WaitForServerReadiness(this->getNS(),"/Registry");
124           NamingService_WaitForServerReadiness(this->getNS(),"/ContainerManager");
125           ActivateContainer(_argc, _argv);
126           break;
127         }
128       case 1:  // ModuleCatalog
129         {
130           NamingService_WaitForServerReadiness(this->getNS(),"/Registry");
131           ActivateModuleCatalog(_argc, _argv);
132           break;
133         }
134       case 2:  // Registry
135         {
136           NamingService_WaitForServerReadiness(this->getNS(),"");
137           ActivateRegistry(_argc, _argv);
138           break;
139         }
140       case 3:  // SALOMEDS
141         {
142           NamingService_WaitForServerReadiness(this->getNS(),"/Kernel/ModulCatalog");
143           ActivateSALOMEDS(_argc, _argv);
144           break;
145         }
146       case 4:  // Session
147         {
148           NamingService_WaitForServerReadiness(this->getNS(),"/Study");
149           std::string containerName = "/Containers/";
150           containerName = containerName + Kernel_Utils::GetHostname();
151           containerName = containerName + "/FactoryServer";
152           NamingService_WaitForServerReadiness(this->getNS(),containerName);
153           ActivateSession(_argc, _argv);
154           break;
155         }
156       case 5: // Container Manager
157         {
158           NamingService_WaitForServerReadiness(this->getNS(),"");
159           ActivateContainerManager(_argc, _argv);
160           break;
161         }
162       default:
163         {
164           ASSERT(0);
165           break;
166         }
167       }
168     }
169   }
170 }
171
172 template<class MY_NS>
173 void Session_ServerThread<MY_NS>::Shutdown()
174 {
175   if ( _container ) _container->Shutdown();
176 }
177
178 template<class MY_NS>
179 void Session_ServerThread<MY_NS>::ActivateModuleCatalog(int argc, char ** argv)
180 {
181   try {
182     MESSAGE("ModuleCatalog thread started");
183     // allocation on heap to allow destruction by POA
184     
185     SALOME_ModuleCatalogImpl* Catalogue_i
186       = new SALOME_ModuleCatalogImpl(argc, argv);
187     
188     // Tell the POA that the objects are ready to accept requests.
189     
190     PortableServer::ObjectId_var id = _root_poa->activate_object (Catalogue_i);
191     Catalogue_i->_remove_ref();
192     
193     CORBA::Object_var myCata = Catalogue_i->_this();
194     _NS->Register(myCata ,"/Kernel/ModulCatalog");
195   }
196   catch(CORBA::SystemException&) {
197     INFOS( "Caught CORBA::SystemException." );
198   }
199   catch(CORBA::Exception&) {
200     INFOS( "Caught CORBA::Exception." );
201   }
202   catch(omniORB::fatalException& fe) {
203     INFOS( "Caught omniORB::fatalException:" );
204     INFOS( "  file: " << fe.file() );
205     INFOS( "  line: " << fe.line() );
206     INFOS( "  mesg: " << fe.errmsg() );
207   }
208   catch(...) {
209     INFOS( "Caught unknown exception." );
210   }
211 }
212
213 template<class MY_NS>
214 void Session_ServerThread<MY_NS>::ActivateSALOMEDS(int /*argc*/, char** /*argv*/)
215 {
216   this->_NS->activateSALOMEDS(this->_orb,this->_root_poa);
217 }
218
219 template<class MY_NS>
220 void Session_ServerThread<MY_NS>::ActivateRegistry(int argc, char ** argv)
221 {
222   MESSAGE("Registry thread started");
223   SCRUTE(argc); 
224   if ( argc<3 ) {
225     INFOS("you must provide the Salome session name when you call SALOME_Registry_Server");
226     throw CommException("you must provide the Salome session name when you call SALOME_Registry_Server");
227   }
228   const char *ptrSessionName=0;
229
230   int k=0 ;
231   for ( k=1 ; k<argc ; k++ ) {
232     if ( strcmp(argv[k],"--salome_session")==0 ) {
233       ptrSessionName=argv[k+1];
234       break;
235     }
236   }
237   ASSERT(ptrSessionName) ;
238   ASSERT(strlen( ptrSessionName )>0);
239   const char *registryName = "Registry";
240   Registry::Components_var varComponents;
241   try {
242     RegistryService *ptrRegistry = new RegistryService;
243     ptrRegistry->SessionName( ptrSessionName );
244     ptrRegistry->SetOrb(_orb);
245     //
246     CORBA::PolicyList policies;
247     policies.length(1);
248     PortableServer::ThreadPolicy_var threadPol(_root_poa->create_thread_policy(PortableServer::SINGLE_THREAD_MODEL));
249     policies[0]=PortableServer::ThreadPolicy::_duplicate(threadPol);
250     PortableServer::POAManager_var manager = _root_poa->the_POAManager();
251     PortableServer::POA_var poa2(_root_poa->create_POA("SingleThreadPOA4RegistryEmbedded",manager,policies));
252     threadPol->destroy();
253     //
254     PortableServer::ObjectId_var id(poa2->activate_object(ptrRegistry));
255     CORBA::Object_var pipo=poa2->id_to_reference(id);
256     varComponents = Registry::Components::_narrow(pipo) ;
257     ptrRegistry->_remove_ref(); //let poa manage registryservice deletion
258     
259     try {
260       CORBA::Object_var pipo = _NS->Resolve( registryName );
261       if (CORBA::is_nil(pipo) )  throw ServiceUnreachable();
262       INFOS("RegistryService servant already existing" );
263       ASSERT(0);
264     }
265     catch( const ServiceUnreachable &/*ex*/ ) {
266     }
267     catch( const CORBA::Exception &/*exx*/ ) {
268     }
269     std::string absoluteName = std::string("/") + registryName;
270     _NS->Register( varComponents , absoluteName.c_str() );
271   }
272   catch( const SALOME_Exception &ex ) {
273     INFOS( "Communication Error : " << ex.what() );
274     ASSERT(0);
275   }
276 }
277
278 template<class MY_NS>
279 void Session_ServerThread<MY_NS>::ActivateContainerManager(int /*argc*/, char** /*argv*/)
280 {
281   this->_NS->activateContainerManager(this->_orb);
282 }
283
284 template<class MY_NS>
285 typename MY_NS::RealNS *Session_ServerThread<MY_NS>::getNS()
286 {
287   MY_NS *pt(_NS.get());
288   if(!pt)
289      THROW_SALOME_EXCEPTION("Session_ServerThread<MY_NS>::getNS : null pointer !");
290   return pt->getNS();
291 }
292
293 template<class MY_NS>
294 void Session_ServerThread<MY_NS>::ActivateContainer(int argc, char** argv)
295 {
296   _container = this->_NS->activateContainer(this->_orb,this->_root_poa,argc,argv);
297 }
298
299 template<class MY_NS>
300 void Session_ServerThread<MY_NS>::ActivateSession(int /*argc*/, char** /*argv*/)
301 {
302   MESSAGE("Session_ServerThread::ActivateSession() not implemented!");
303 }
304
305 template<class MY_NS>
306 Session_SessionThread<MY_NS>::Session_SessionThread(int argc,
307                                              char** argv, 
308                                              CORBA::ORB_ptr orb, 
309                                              PortableServer::POA_ptr poa,
310                                              QMutex* GUIMutex,
311                                              QWaitCondition* GUILauncher)
312 : Session_ServerThread<MY_NS>(argc, argv, orb, poa),
313   _GUIMutex( GUIMutex ),
314   _GUILauncher( GUILauncher )
315 {
316 }
317
318 template<class MY_NS>
319 Session_SessionThread<MY_NS>::~Session_SessionThread()
320 {
321 }
322
323 template<class MY_NS>
324 void Session_SessionThread<MY_NS>::ActivateSession(int argc, char ** argv)
325 {
326   this->_NS->activateSession(this->_orb,this->_root_poa,_GUIMutex,_GUILauncher,argc,argv);
327 }
328
329 template class Session_ServerThread<OldStyleNS>;
330 template class Session_SessionThread<OldStyleNS>;
331
332 template class Session_ServerThread<NewStyleNS>;
333 template class Session_SessionThread<NewStyleNS>;