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