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