Salome HOME
Updated copyright comment
[modules/gui.git] / src / Session / Session_ServerLauncher.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_ServerLauncher.cxx
24 //  File   : Session_ServerLauncher.xx
25 //  Author : Paul RASCLE, EDF
26
27 #include "Session_ServerLauncher.hxx"
28 #include "Session_ServerThread.hxx"
29
30 #include "Utils_SALOME_Exception.hxx"
31 #include "utilities.h"
32
33 #include <QMutex>
34 #include <QWaitCondition>
35
36 /*! 
37    default constructor not for use
38  */
39 template<class MY_NS>
40 Session_ServerLauncher<MY_NS>::Session_ServerLauncher()
41 {
42   ASSERT(0); // must not be called
43 }
44
45 /*! 
46   constructor
47 */
48 template<class MY_NS>
49 Session_ServerLauncher<MY_NS>::Session_ServerLauncher(int argc,
50                                                       char ** argv, 
51                                                       CORBA::ORB_ptr orb, 
52                                                       PortableServer::POA_ptr poa,
53                                                       QMutex *GUIMutex,
54                                                       QWaitCondition *ServerLaunch,
55                                                       QMutex *SessionMutex,
56                                                       QWaitCondition *SessionStarted)
57 {
58   _argc = argc;
59   _argv = argv;
60   _orb = CORBA::ORB::_duplicate(orb);
61   _root_poa = PortableServer::POA::_duplicate(poa);
62   _GUIMutex = GUIMutex;
63   _ServerLaunch = ServerLaunch;
64   _SessionMutex = SessionMutex;
65   _SessionStarted = SessionStarted;
66   MY_NS::defineDefaultSALOMEKERNELNamingService();
67   // start thread
68   start();
69 }
70
71 /*! 
72   destructor
73 */
74 template<class MY_NS>
75 Session_ServerLauncher<MY_NS>::~Session_ServerLauncher()
76 {
77 }
78
79 /*! 
80   Check args and activate servers
81 */
82 template<class MY_NS>
83 void Session_ServerLauncher<MY_NS>::run()
84 {
85   // wait until main thread is ready
86   _GUIMutex->lock();          // ... lock mutex (it is unlocked my calling thread 
87                               // wait condition's wait(mutex)
88   _GUIMutex->unlock();        // ... and unlock it 'cause it is not more needed
89
90   // wake main thread
91   _ServerLaunch->wakeAll();
92
93   CheckArgs();
94   ActivateAll();
95
96   // wait until main thread is ready
97   _GUIMutex->lock();          // ... lock mutex (it is unlocked my calling thread 
98                               // wait condition's wait(mutex)
99   _GUIMutex->unlock();        // ... and unlock it 'cause it is not more needed
100
101   // wake main thread
102   _ServerLaunch->wakeAll();
103
104   // run ORB
105   //_orb->run(); // No need to call orb->run() : it waits on a lock. Qt is already waiting in the mainloop.
106 }
107
108 /*! 
109   controls and dispatchs arguments given with command
110 */
111 template<class MY_NS>
112 void Session_ServerLauncher<MY_NS>::CheckArgs()
113 {
114   int argState = 0;
115   ServArg aServArg(0,0,0);
116   _argCopy.reserve(_argc);
117   for (int iarg=0; iarg <_argc; iarg++)
118     {
119       //SCRUTE(iarg);
120       //SCRUTE(_argv[iarg]);
121       _argCopy.push_back(_argv[iarg]);
122       switch (argState)
123         {
124         case 0: // looking for "--with"
125           {
126             if (strcmp(_argv[iarg],"--with")==0)
127               argState = 1;
128             break;
129           }
130         case 1: // looking for server type
131           {
132             // Temporary solution
133             // Issue 21337 - no more SalomeApp_Engine_i activation here
134             // TODO: To be removed as soon as any trace of SalomeAppEngine
135             // has been eliminated from KERNEL scripts
136             if (strcmp(_argv[iarg], "SalomeAppEngine")==0){
137               argState = 0;
138               iarg += 2; // skipping "()" 
139               break;
140             }
141             // Temporary solution
142
143             for (int i=0; i<Session_ServerThread<MY_NS>::NB_SRV_TYP; i++)
144                 if (strcmp(_argv[iarg],Session_ServerThread<MY_NS>::_serverTypes[i])==0)
145                   {
146                     aServArg._servType = i;
147                     argState = 2;
148                     break;
149                   }
150             break;
151           }
152         case 2: // looking for "("
153           {
154             if (strcmp(_argv[iarg],"(")!=0)
155               {
156                 INFOS("parenthesis '(' is required here...");
157                 for (int i=0; i<iarg; i++)
158                   std::cerr << _argv[i] << " ";
159                 std::cerr << std::endl;
160                 throw SALOME_Exception(LOCALIZED("Error in command arguments, missing prenthesis"));
161               } 
162             else
163               {
164                 aServArg._firstArg=iarg+1;    // arg after '('
165                 argState = 3;
166               }
167             break;
168           }
169         case 3: // looking for arguments
170           {
171             if (strcmp(_argv[iarg],")")==0)   // end of arguments = ')'
172               {
173                 aServArg._lastArg=iarg-1;     // arg before ')'
174                 MESSAGE("server : "<< Session_ServerThread<MY_NS>::_serverTypes[aServArg._servType]);
175                 for (int i=aServArg._firstArg; i<=aServArg._lastArg; i++)
176                   MESSAGE("  arg : " << _argCopy[i]);
177                 _argServToLaunch.push_back(aServArg);
178                 argState = 0;
179               } 
180             break;
181           }
182         default:
183           {
184             ASSERT(0);
185             break;
186           }
187         }
188     }
189   if (argState == 1)
190     throw SALOME_Exception(LOCALIZED("Error in command arguments, missing server type"));
191   if (argState == 2)
192     throw SALOME_Exception(LOCALIZED("Error in command arguments, missing parenthesis '('"));
193   if (argState == 3)
194     throw SALOME_Exception(LOCALIZED("Error in command arguments, missing parenthesis ')'"));
195 }
196
197 template<class MY_NS>
198 void Session_ServerLauncher<MY_NS>::ActivateAll()
199 {
200   std::list<ServArg>::iterator itServ;
201   for (itServ = _argServToLaunch.begin(); itServ !=_argServToLaunch.end(); itServ++)
202   {
203     int argc = 2 + (*itServ)._lastArg - (*itServ)._firstArg;
204     char** argv = new char*[argc+1];
205     argv[argc]=0; // for Engines_Container_i constructor...
206     int servType = (*itServ)._servType;
207     argv[0]=strdup(Session_ServerThread<MY_NS>::_serverTypes[servType]);
208     if (argc>1)
209     {
210       for (int i=0; i<argc-1; i++)
211         //argv[i+1] = _argCopy[(*itServ)._firstArg + i].c_str();
212               argv[i+1] = _argv[(*itServ)._firstArg + i];
213     }
214
215     MESSAGE("*** activating [" << argc << "] : " << argv[0]);
216
217     Session_ServerThread<MY_NS>* aServerThread = new Session_ServerThread<MY_NS>(argc, argv, _orb,_root_poa);
218     _serverThreads.push_front(aServerThread);
219     
220     aServerThread->Init();
221     free( argv[0] );
222     delete[] argv;
223   }
224
225   // Always launch Session Server
226   MESSAGE("*** activating [ SESSION ] ");
227
228   int argc=1;
229   char** argv = new char*[argc];
230   argv[0] = (char*)"Session";
231   Session_SessionThread<MY_NS>* aServerThread
232     = new Session_SessionThread<MY_NS>(argc, argv, _orb,_root_poa,_SessionMutex,_SessionStarted);
233   _serverThreads.push_front(aServerThread);
234   aServerThread->Init();
235   delete[] argv;
236 }
237
238 template <class MY_NS>
239 void Session_ServerLauncher<MY_NS>::ShutdownAll()
240 {
241   MESSAGE("Session_ServerLauncher::ShutdownAll()");
242   using Session_ServerThreadT = Session_ServerThread<MY_NS>;
243   typename std::list<Session_ServerThreadT*>::reverse_iterator itServ;
244   for (itServ = _serverThreads.rbegin(); itServ !=_serverThreads.rend(); itServ++)
245   {
246     (*itServ)->Shutdown();
247   }
248 }
249
250 /*! 
251   Destruction des classes serveur dans l'ordre inverse de creation
252 */
253 template <class MY_NS>
254 void Session_ServerLauncher<MY_NS>::KillAll()
255 {
256   MESSAGE("Session_ServerLauncher::KillAll()");
257   using Session_ServerThreadT = Session_ServerThread<MY_NS>;
258   typename std::list<Session_ServerThreadT*>::reverse_iterator itServ;
259   for (itServ = _serverThreads.rbegin(); itServ !=_serverThreads.rend(); itServ++)
260   {
261     delete (*itServ);
262   }
263 }
264
265 #include "Session_NS_wrapper.hxx" 
266
267 template class Session_ServerLauncher<OldStyleNS>;
268
269 template class Session_ServerLauncher<NewStyleNS>;