Salome HOME
destroy kernel in naming service on shutdown
[modules/gui.git] / src / Session / Session_Session_i.cxx
1 // Copyright (C) 2007-2019  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 //  File   : SALOME_Session_i.cxx
23 //  Author : Paul RASCLE, EDF
24 //  Module : SALOME
25
26 #include "utilities.h"
27
28 #include "Session_Session_i.hxx"
29
30 #include "SALOME_NamingService.hxx"
31 #include "SALOME_Event.h"
32 #include "SalomeApp_Engine_i.h"
33 #include "LightApp_Application.h"
34 #include "LightApp_SelectionMgr.h"
35 #include "SALOME_ListIO.hxx"
36 #include "SUIT_Session.h"
37 #include "SUIT_Desktop.h"
38 #include "SUIT_Study.h"
39
40 #include "Basics_Utils.hxx"
41
42 #include <QMutex>
43 #include <QWaitCondition>
44
45 // Open CASCADE Includes
46 #include <OSD_SharedLibrary.hxx>
47 #include <OSD_Function.hxx>
48
49 #ifdef WIN32
50 # include <process.h>
51 #else
52 #include <unistd.h>
53 #endif
54
55 /*!
56   constructor
57 */
58 SALOME_Session_i::SALOME_Session_i(int argc,
59                                    char ** argv,
60                                    CORBA::ORB_ptr orb,
61                                    PortableServer::POA_ptr poa,
62                                    QMutex* GUIMutex,
63                                    QWaitCondition* GUILauncher)
64 {
65   _argc = argc ;
66   _argv = argv ;
67   _isGUI = false ;
68   _orb = CORBA::ORB::_duplicate(orb) ;
69   _poa = PortableServer::POA::_duplicate(poa) ;
70   _GUIMutex = GUIMutex;
71   _GUILauncher = GUILauncher;
72   _NS = new SALOME_NamingService(_orb);
73   _isShuttingDown = false;
74   //MESSAGE("constructor end");
75 }
76
77 /*!
78   returns Visu component
79 */
80 Engines::EngineComponent_ptr SALOME_Session_i::GetComponent(const char* theLibraryName)
81 {
82   typedef Engines::EngineComponent_ptr TGetImpl(CORBA::ORB_ptr,
83                                                 PortableServer::POA_ptr,
84                                                 SALOME_NamingService*,QMutex*);
85   OSD_SharedLibrary aSharedLibrary(const_cast<char*>(theLibraryName));
86   if (aSharedLibrary.DlOpen(OSD_RTLD_LAZY)) {
87     if (OSD_Function anOSDFun = aSharedLibrary.DlSymb("GetImpl"))
88       return ((TGetImpl (*)) anOSDFun)(_orb,_poa,_NS,_GUIMutex);
89   }
90   CORBA::Object_var obj = SalomeApp_Engine_i::EngineForComponent(theLibraryName, true);
91   if (!CORBA::is_nil(obj)){
92     Engines::EngineComponent_var anEngine = Engines::EngineComponent::_narrow(obj);
93     return anEngine._retn();
94   }
95   return Engines::EngineComponent::_nil();
96 }
97
98 /*!
99   destructor
100 */
101 SALOME_Session_i::~SALOME_Session_i()
102 {
103   delete _NS;
104   //MESSAGE("destructor end");
105 }
106
107 /*!
108   tries to find the Corba Naming Service and to register the session,
109   gives naming service interface to _IAPPThread
110 */
111 void SALOME_Session_i::NSregister()
112 {
113   CORBA::Object_var obref=_this();
114   SALOME::Session_var pSession = SALOME::Session::_narrow(obref);
115   try
116     {
117       _NS->Register(pSession, "/Kernel/Session");
118     }
119   catch (ServiceUnreachable&)
120     {
121       INFOS("Caught exception: Naming Service Unreachable");
122       exit(1) ;
123     }
124   catch (...)
125     {
126       INFOS("Caught unknown exception from Naming Service");
127     }
128   //MESSAGE("Session registered in Naming Service");
129 }
130
131 /*!
132   Unregister session server from CORBA Naming Service
133 */
134 void SALOME_Session_i::NSunregister()
135 {
136   try
137     {
138       _NS->Destroy_Name("/Kernel/Session");
139       _NS->Destroy_Directory("/Kernel");
140     }
141   catch (ServiceUnreachable&)
142     {
143       INFOS("Caught exception: Naming Service Unreachable");
144     }
145   catch (...)
146     {
147       INFOS("Caught unknown exception from Naming Service");
148     }
149 }
150
151 /*!
152   Launches the GUI if there is none.
153   The Corba method is oneway (corba client does'nt wait for GUI completion)
154 */
155 void SALOME_Session_i::GetInterface()
156 {
157   _GUIMutex->lock();
158   _GUIMutex->unlock();
159   if ( !SUIT_Session::session() )
160   {
161     _GUILauncher->wakeAll();
162     MESSAGE("SALOME_Session_i::GetInterface() called, starting GUI...");
163   }
164 }
165
166 /*!
167   Kills the session if there are no active studies nore GUI
168 */
169 class CloseEvent : public SALOME_Event
170 {
171 public:
172   virtual void Execute() {
173     if ( SUIT_Session::session() )
174       SUIT_Session::session()->closeSession( SUIT_Session::DONT_SAVE );
175   }
176 };
177
178 /*!
179   Stop session (close all GUI windows)
180 */
181 void SALOME_Session_i::StopSession()
182 {
183   _GUIMutex->lock();
184   _GUIMutex->unlock();
185   if ( SUIT_Session::session() ) {
186     ProcessVoidEvent( new CloseEvent() );
187   }
188 }
189
190 //! Shutdown session
191 void SALOME_Session_i::Shutdown()
192 {
193   _GUIMutex->lock();
194   bool isBeingShuttingDown = _isShuttingDown;
195   _isShuttingDown = true;
196   _GUIMutex->unlock();
197   if ( !isBeingShuttingDown ) {
198     if ( SUIT_Session::session() ) {
199       ProcessVoidEvent( new CloseEvent() );
200     }
201     else {
202       _GUILauncher->wakeAll();
203     }
204   }
205 }
206
207 /*!
208   Send a SALOME::StatSession structure (see idl) to the client
209   (presence of GUI)
210 */
211 /*class QtLock
212 {
213 public:
214   QtLock() { if ( qApp ) qApp->lock(); }
215   ~QtLock() { if ( qApp ) qApp->unlock(); }
216 };*/
217
218
219 SALOME::StatSession SALOME_Session_i::GetStatSession()
220 {
221   // update Session state
222   _GUIMutex->lock();
223   int activeStudy = 0;
224
225   {
226     //QtLock lock;
227     _isGUI = SUIT_Session::session();
228     if ( _isGUI && SUIT_Session::session()->activeApplication() )
229       activeStudy = SUIT_Session::session()->activeApplication()->getNbStudies();
230   }
231
232   // getting stat info
233   SALOME::StatSession_var myStats = new SALOME::StatSession;
234   if (activeStudy)
235     myStats->state = SALOME::running ;
236   else if (_isShuttingDown)
237     myStats->state = SALOME::shutdown ;
238   else
239     myStats->state = SALOME::asleep ;
240   myStats->activeGUI = _isGUI ;
241
242   _GUIMutex->unlock();
243
244   return myStats._retn() ;
245 }
246
247 CORBA::Long SALOME_Session_i::getPID() {
248   return (CORBA::Long)
249 #ifndef WIN32
250     getpid();
251 #else
252     _getpid();
253 #endif
254 }
255
256 char* SALOME_Session_i::getHostname()
257 {
258   std::string aHostName = Kernel_Utils::GetHostname();
259   return CORBA::string_dup( aHostName.data() );
260 }
261
262 bool SALOME_Session_i::restoreVisualState(CORBA::Long theSavePoint)
263 {
264   class TEvent: public SALOME_Event {
265     int _savePoint;
266   public:
267     TEvent(int savePoint) { _savePoint = savePoint; }
268     virtual void Execute() {
269       SUIT_Study* study = SUIT_Session::session()->activeApplication()->activeStudy();
270       if ( study ) {
271         study->restoreState(_savePoint);
272       }
273     }
274   };
275   
276   if(SUIT_Session::session() && SUIT_Session::session()->activeApplication() ) {
277     SUIT_Study* study = SUIT_Session::session()->activeApplication()->activeStudy();
278     if(!study) SUIT_Session::session()->activeApplication()->createEmptyStudy();      
279     ProcessVoidEvent( new TEvent(theSavePoint) );
280     return true;
281   }
282  
283   return false;
284 }
285
286 void SALOME_Session_i::emitMessage(const char* theMessage)
287 {
288   class TEvent: public SALOME_Event {
289   public:
290     TEvent(const char * msg) {
291       _msg = msg;
292     }
293     virtual void Execute() {
294       SUIT_Session::session()->activeApplication()->desktop()->emitMessage(_msg);
295     }
296   private:
297     const char* _msg;
298   };
299   if ( SUIT_Session::session() ) {
300     if ( SUIT_Session::session()->activeApplication() ) {
301       if ( SUIT_Session::session()->activeApplication()->desktop() ) {
302         ProcessVoidEvent( new TEvent(theMessage) );
303       }
304       else {
305         MESSAGE("try to emit message '"<<theMessage<<"' but there is no desktop");
306       }
307     }
308     else {
309       MESSAGE("try to emit message '"<<theMessage<<"' but there is no application");
310     }
311   }
312   else {
313     MESSAGE("try to emit message '"<<theMessage<<"' but there is no session");
314   }
315 }
316
317 void SALOME_Session_i::emitMessageOneWay(const char* theMessage)
318 {
319   emitMessage(theMessage);
320 }
321
322 SALOME::StringSeq* SALOME_Session_i::getSelection()
323 {
324   SALOME::StringSeq_var selection = new SALOME::StringSeq;
325   _GUIMutex->lock();
326   if ( SUIT_Session::session() ) {
327     LightApp_Application* app = dynamic_cast<LightApp_Application*>( SUIT_Session::session()->activeApplication() );
328     if ( app ) {
329       LightApp_SelectionMgr* selMgr = dynamic_cast<LightApp_SelectionMgr*>( app->selectionMgr() );
330       SALOME_ListIO selected;
331       selMgr->selectedObjects( selected );
332       selection->length( selected.Extent() );
333       int nbSel = 0;
334       for ( SALOME_ListIteratorOfListIO it( selected ); it.More(); it.Next() ) {
335         Handle( SALOME_InteractiveObject ) io = it.Value();
336         if ( io->hasEntry() )
337           selection[nbSel++] = CORBA::string_dup( io->getEntry() );
338       }
339       selection->length( nbSel );
340     }
341   }
342   _GUIMutex->unlock();
343   return selection._retn();
344 }