From f9cc7174095541763379ee1e80d5df948bd08a72 Mon Sep 17 00:00:00 2001 From: vsr Date: Tue, 2 May 2006 10:42:09 +0000 Subject: [PATCH] Improve splash screen --- src/Session/Makefile.in | 5 +- src/Session/SALOME_Session_Server.cxx | 213 +++++++---- src/Session/Session_ServerCheck.cxx | 509 +++++++++++++++++++++++++ src/Session/Session_ServerCheck.hxx | 62 +++ src/Session/Session_ServerLauncher.cxx | 28 +- src/Session/Session_ServerLauncher.hxx | 16 +- src/Session/Session_ServerThread.cxx | 7 +- src/Session/Session_ServerThread.hxx | 5 +- 8 files changed, 754 insertions(+), 91 deletions(-) create mode 100644 src/Session/Session_ServerCheck.cxx create mode 100644 src/Session/Session_ServerCheck.hxx diff --git a/src/Session/Makefile.in b/src/Session/Makefile.in index bfba47099..27974b91f 100755 --- a/src/Session/Makefile.in +++ b/src/Session/Makefile.in @@ -38,6 +38,7 @@ VPATH=.:@srcdir@:@top_srcdir@/idl EXPORT_HEADERS= Session_Session_i.hxx \ Session_ServerLauncher.hxx \ Session_ServerThread.hxx \ + Session_ServerCheck.hxx \ SalomeApp_Engine_i.hxx # Libraries targets @@ -46,10 +47,10 @@ LIB = libSalomeSession.la LIB_SRC=Session_Session_i.cxx \ Session_ServerThread.cxx \ Session_ServerLauncher.cxx \ + Session_ServerCheck.cxx \ SalomeApp_Engine_i.cxx \ - InquireServersQThread.cxx -LIB_MOC = InquireServersQThread.h +LIB_MOC = # Executables targets BIN = SALOME_Session_Server diff --git a/src/Session/SALOME_Session_Server.cxx b/src/Session/SALOME_Session_Server.cxx index 02741922e..55985e7ee 100755 --- a/src/Session/SALOME_Session_Server.cxx +++ b/src/Session/SALOME_Session_Server.cxx @@ -31,8 +31,6 @@ #include "SALOME_NamingService.hxx" #include "SALOMETraceCollector.hxx" -#include "InquireServersQThread.h" // splash - #include #ifndef WNT #include @@ -55,13 +53,15 @@ #include #include "Session_Session_i.hxx" #include "Session_ServerLauncher.hxx" +#include "Session_ServerCheck.hxx" +#include #include "SUIT_Tools.h" #include "SUIT_Session.h" #include "SUIT_Application.h" +#include "SUIT_Desktop.h" #include "SUIT_MessageBox.h" #include "SUIT_ResourceMgr.h" - #include "SUIT_ExceptionHandler.h" /*! - read arguments, define list of server to launch with their arguments. @@ -261,7 +261,10 @@ private: class GetInterfaceThread : public QThread { public: - GetInterfaceThread( SALOME::Session_var s ) : session ( s ) {} + GetInterfaceThread( SALOME::Session_var s ) : session ( s ) + { + start(); + } protected: virtual void run() { @@ -286,19 +289,87 @@ bool isFound( const char* str, int argc, char** argv ) // ---------------------------- MAIN ----------------------- int main( int argc, char **argv ) { + // Install Qt debug messages handler qInstallMsgHandler( MessageOutput ); - - // QApplication should be create before all other operations - // When uses QApplication::libraryPaths() ( example, QFile::encodeName() ) - // qApp used for detection of the executable dir path. + + // Create Qt application instance; + // this should be done the very first! SALOME_QApplication _qappl( argc, argv ); ASSERT( QObject::connect( &_qappl, SIGNAL( lastWindowClosed() ), &_qappl, SLOT( quit() ) ) ); + // Add application library path (to search style plugin etc...) QString path = QDir::convertSeparators( SUIT_Tools::addSlash( QString( ::getenv( "GUI_ROOT_DIR" ) ) ) + QString( "bin/salome" ) ); _qappl.addLibraryPath( path ); + // Set SALOME style to the application _qappl.setStyle( "salome" ); + bool isGUI = isFound( "GUI", argc, argv ); + bool isSplash = isFound( "SPLASH", argc, argv ); + // Show splash screen (only if both the "GUI" and "SPLASH" parameters are set) + QtxSplash* splash = 0; + if ( isGUI && isSplash ) { + // ...create resource manager + SUIT_ResourceMgr resMgr( "SalomeApp", QString( "%1Config" ) ); + resMgr.setCurrentFormat( "xml" ); + resMgr.loadLanguage( "LightApp", "en" ); + // ...get splash preferences + QString splashIcon, splashInfo, splashTextColors, splashProgressColors; + resMgr.value( "splash", "image", splashIcon ); + resMgr.value( "splash", "info", splashInfo, false ); + resMgr.value( "splash", "text_colors", splashTextColors ); + resMgr.value( "splash", "progress_colors", splashProgressColors ); + QPixmap px( splashIcon ); + if ( px.isNull() ) // try to get splash pixmap from resources + px = resMgr.loadPixmap( "LightApp", QObject::tr( "ABOUT_SPLASH" ) ); + if ( !px.isNull() ) { + // ...set splash pixmap + splash = QtxSplash::splash( px ); + // ...set splash text colors + if ( !splashTextColors.isEmpty() ) { + QStringList colors = QStringList::split( "|", splashTextColors ); + QColor c1, c2; + if ( colors.count() > 0 ) c1 = QColor( colors[0] ); + if ( colors.count() > 1 ) c2 = QColor( colors[1] ); + splash->setTextColors( c1, c2 ); + } + else { + splash->setTextColors( Qt::white, Qt::black ); + } + // ...set splash progress colors + if ( !splashProgressColors.isEmpty() ) { + QStringList colors = QStringList::split( "|", splashProgressColors ); + QColor c1, c2; + int gradType = QtxSplash::Vertical; + if ( colors.count() > 0 ) c1 = QColor( colors[0] ); + if ( colors.count() > 1 ) c2 = QColor( colors[1] ); + if ( colors.count() > 2 ) gradType = colors[2].toInt(); + splash->setProgressColors( c1, c2, gradType ); + } + // ...set splash text font + QFont f = splash->font(); + f.setBold( true ); + splash->setFont( f ); + // ...show splash initial status + if ( !splashInfo.isEmpty() ) { + splashInfo.replace( QRegExp( "%A" ), QObject::tr( "APP_NAME" ) ); + splashInfo.replace( QRegExp( "%V" ), QObject::tr( "ABOUT_VERSION" ).arg( salomeVersion() ) ); + splashInfo.replace( QRegExp( "%L" ), QObject::tr( "ABOUT_LICENSE" ) ); + splashInfo.replace( QRegExp( "%C" ), QObject::tr( "ABOUT_COPYRIGHT" ) ); + splashInfo.replace( QRegExp( "\\\\n" ), "\n" ); + splash->message( splashInfo ); + } + // ...set 'hide on click' flag +#ifdef _DEBUG_ + splash->setHideOnClick( true ); +#endif + // ...show splash + splash->show(); + qApp->processEvents(); + } + } + + // Initialization int result = -1; CORBA::ORB_var orb; @@ -310,29 +381,26 @@ int main( int argc, char **argv ) Session_ServerLauncher* myServerLauncher = 0; try { - - // Python initialisation : only once - - int _argc = 1; + // ...initialize Python (only once) + int _argc = 1; char* _argv[] = {""}; KERNEL_PYTHON::init_python( _argc,_argv ); PyEval_RestoreThread( KERNEL_PYTHON::_gtstate ); if ( !KERNEL_PYTHON::salome_shared_modules_module ) // import only once KERNEL_PYTHON::salome_shared_modules_module = PyImport_ImportModule( "salome_shared_modules" ); - if ( !KERNEL_PYTHON::salome_shared_modules_module ) - { + if ( !KERNEL_PYTHON::salome_shared_modules_module ) { INFOS( "salome_shared_modules_module == NULL" ); PyErr_Print(); } PyEval_ReleaseThread( KERNEL_PYTHON::_gtstate ); - // Create ORB, get RootPOA object, NamingService, etc. + // ...create ORB, get RootPOA object, NamingService, etc. ORB_INIT &init = *SINGLETON_::Instance(); ASSERT( SINGLETON_::IsAlreadyExisting() ); int orbArgc = 1; orb = init( orbArgc, argv ); - // Install SALOME thread event handler + // ...install SALOME thread event handler SALOME_Event::GetSessionThread(); CORBA::Object_var obj = orb->resolve_initial_references( "RootPOA" ); @@ -367,71 +435,67 @@ int main( int argc, char **argv ) INFOS( "Caught unknown exception." ); } - // CORBA Servant Launcher - QMutex _GUIMutex; - QWaitCondition _ServerLaunch, _SessionStarted; - - if ( !result ) - { - _GUIMutex.lock(); // to block Launch server thread until wait( mutex ) - - // Activate embedded CORBA servers: Registry, SALOMEDS, etc. - myServerLauncher = new Session_ServerLauncher( argc, argv, orb, poa, &_GUIMutex, &_ServerLaunch, &_SessionStarted ); - myServerLauncher->start(); - - _ServerLaunch.wait( &_GUIMutex ); // to be reseased by Launch server thread when ready: + QMutex _GUIMutex, _SessionMutex, _SplashMutex; + QWaitCondition _ServerLaunch, _SessionStarted, _SplashStarted; + + // lock session mutex to ensure that GetInterface is not called + // until all initialization is done + _SessionMutex.lock(); + + if ( !result ) { + // Start embedded servers launcher (Registry, SALOMEDS, etc.) + // ...lock mutex to block embedded servers launching thread until wait( mutex ) + _GUIMutex.lock(); + // ...create launcher + myServerLauncher = new Session_ServerLauncher( argc, argv, orb, poa, &_GUIMutex, &_ServerLaunch, &_SessionMutex, &_SessionStarted ); + // ...block this thread until launcher is ready + _ServerLaunch.wait( &_GUIMutex ); - // show splash screen if "SPLASH" parameter was passed ( default ) - - - if ( isFound( "SPLASH", argc, argv ) ) { - InquireServersGUI splash; - - // create temporary resource manager just to load splash icon - SUIT_ResourceMgr resMgr( "SalomeApp", QString( "%1Config" ) ); - resMgr.setCurrentFormat( "xml" ); - resMgr.loadLanguage( "LightApp", "en" ); - - // create splash object: widget ( splash with progress bar ) and "pinging" thread - splash.setPixmap( resMgr.loadPixmap( "LightApp", QObject::tr( "ABOUT_SPLASH" ) ) ); - SUIT_Tools::centerWidget( &splash, _qappl.desktop() ); - - _qappl.setMainWidget( &splash ); - QObject::connect( &_qappl, SIGNAL( lastWindowClosed() ), &_qappl, SLOT( quit() ) ); - splash.show(); // display splash with running progress bar - _qappl.exec(); // wait untill splash closes ( progress runs till end or Cancel is pressed ) - result = splash.getExitStatus(); // 1 is error + // Start servers check thread (splash) + if ( splash ) { + // ...lock mutex to block splash thread until wait( mutex ) + _SplashMutex.lock(); + // ...create servers checking thread + Session_ServerCheck sc( &_SplashMutex, &_SplashStarted ); + // ...block this thread until servers checking is finished + _SplashStarted.wait( &_SplashMutex ); + // ...unlock mutex 'cause it is no more needed + _SplashMutex.unlock(); + // get servers checking thread status + result = splash->error(); + QString info = splash->message().isEmpty() ? "%1" : QString( "%1\n%2" ).arg( splash->message() ); + splash->setStatus( info.arg( "Activating desktop..." ) ); } - else - _SessionStarted.wait(); - } - // call Session::GetInterface() if "GUI" parameter was passed ( default ) - if ( !result && isFound( "GUI", argc, argv ) ) - { - CORBA::Object_var obj = _NS->Resolve( "/Kernel/Session" ); - SALOME::Session_var session = SALOME::Session::_narrow( obj ) ; - ASSERT ( ! CORBA::is_nil( session ) ); - - INFOS( "Session activated, Launch IAPP..." ); - guiThread = new GetInterfaceThread( session ); - guiThread->start(); + // Finalize embedded servers launcher + // ...block this thread until launcher is finished + _ServerLaunch.wait( &_GUIMutex ); + // ...unlock mutex 'cause it is no more needed + _GUIMutex.unlock(); } - if ( !result ) - { + if ( !result ) { + // Launch GUI activator + if ( isGUI ) { + // ...retrieve Session interface reference + CORBA::Object_var obj = _NS->Resolve( "/Kernel/Session" ); + SALOME::Session_var session = SALOME::Session::_narrow( obj ) ; + ASSERT ( ! CORBA::is_nil( session ) ); + // ...create GUI launcher + INFOS( "Session activated, Launch IAPP..." ); + guiThread = new GetInterfaceThread( session ); + } // GUI activation // Allow multiple activation/deactivation of GUI - while ( true ) - { + while ( true ) { MESSAGE( "waiting wakeAll()" ); - _ServerLaunch.wait( &_GUIMutex ); // to be reseased by Launch server thread when ready: + _SessionStarted.wait( &_SessionMutex ); // to be reseased by Launch server thread when ready: // atomic operation lock - unlock on mutex // unlock mutex: serverThread runs, calls _ServerLaunch->wakeAll() // this thread wakes up, and lock mutex - _GUIMutex.unlock(); + _SessionMutex.unlock(); // SUIT_Session creation aGUISession = new SALOME_Session(); @@ -446,7 +510,15 @@ int main( int argc, char **argv ) // aGUISession contains SalomeApp_ExceptionHandler // Run GUI loop MESSAGE( "run(): starting the main event loop" ); + + if ( splash ) + splash->finish( aGUIApp->desktop() ); + result = _qappl.exec(); + + if ( splash ) + delete splash; + splash = 0; if ( result == SUIT_Session::FROM_GUI ) // desktop is closed by user from GUI break; @@ -456,10 +528,13 @@ int main( int argc, char **argv ) aGUISession = 0; // Prepare _GUIMutex for a new GUI activation - _GUIMutex.lock(); + _SessionMutex.lock(); } } + // unlock Session mutex + _SessionMutex.unlock(); + if ( myServerLauncher ) myServerLauncher->KillAll(); // kill embedded servers diff --git a/src/Session/Session_ServerCheck.cxx b/src/Session/Session_ServerCheck.cxx new file mode 100644 index 000000000..ac4c59c1b --- /dev/null +++ b/src/Session/Session_ServerCheck.cxx @@ -0,0 +1,509 @@ +// Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ +// +// File: Session_ServerCheck.cxx +// Author: Vadim SANDLER + +#include "Session_ServerCheck.hxx" +#include + +#include +#include CORBA_CLIENT_HEADER(SALOME_Session) +#include CORBA_CLIENT_HEADER(SALOME_Registry) +#include CORBA_CLIENT_HEADER(SALOMEDS) +#include CORBA_CLIENT_HEADER(SALOME_ModuleCatalog) +#include CORBA_CLIENT_HEADER(SALOME_Component) + +#include "Utils_ORB_INIT.hxx" +#include "Utils_SINGLETON.hxx" +#include "SALOME_NamingService.hxx" +#include "utilities.h" +#include "OpUtil.hxx" + +// Default settings +const int __DEFAULT__ATTEMPTS__ = 300; // number of checks attemtps + // can be overrided by CSF_RepeatServerRequest + // environment variable +const int __DEFAULT__DELAY__ = 100000; // delay between attempts (microseconds) + // can be overrided by CSF_DelayServerRequest + // environment variable + +/*! + Constructor +*/ +Session_ServerCheck::Session_ServerCheck( QMutex* mutex, QWaitCondition* wc ) + : QThread(), + myMutex( mutex ), + myWC( wc ), + myCheckCppContainer( false ), + myCheckPyContainer( false ), + myCheckSVContainer( false ), + myAttempts( __DEFAULT__ATTEMPTS__ ), + myDelay ( __DEFAULT__DELAY__ ) +{ + char* cenv; + // try to get nb of attempts from environment variable + if ( ( cenv = getenv( "CSF_RepeatServerRequest" ) ) && atoi( cenv ) > 0 ) + myAttempts = atoi( cenv ); + // try to get delay between attempts from environment variable + if ( ( cenv = getenv( "CSF_DelayServerRequest" ) ) && atoi( cenv ) > 0 ) + myDelay = atoi( cenv ); + + // check if it is necessary to wait containers + for ( int i = 1; i < qApp->argc(); i++ ) { + if ( !strcmp( qApp->argv()[i], "CPP" ) ) + myCheckCppContainer = true; + if ( !strcmp( qApp->argv()[i], "PY" ) ) + myCheckPyContainer = true; + if ( !strcmp( qApp->argv()[i], "SUPERV" ) ) + myCheckSVContainer = true; + } + + // start thread + start(); +} + +/*! + Destructor +*/ +Session_ServerCheck::~Session_ServerCheck() +{ +} + +/*! + Thread loop. Checnk SALOME servers and shows status message + in the splash screen. +*/ +void Session_ServerCheck::run() +{ + // automatic locker + class Locker + { + public: + QMutex* _m; + QWaitCondition* _wc; + Locker( QMutex* m, QWaitCondition* wc ) : _m( m ), _wc( wc ) + { + _m->lock(); + _m->unlock(); + } + ~Locker() + { + _wc->wakeAll(); + } + }; + + // lock mutex (ensure splash is shown) + Locker locker( myMutex, myWC ); + + // set initial splash status + QtxSplash* splash = QtxSplash::splash(); + + int cnt = 5; // base servers + if ( myCheckCppContainer ) cnt++; // + C++ container + if ( myCheckPyContainer ) cnt++; // + Python container + if ( myCheckSVContainer ) cnt++; // + supervision container + + splash->setProgress( 0, cnt * myAttempts ); + QString initialInfo = splash->message(); + QString info = initialInfo.isEmpty() ? "%1" : QString( "%1\n%2" ).arg( initialInfo ); + + // start check servers + int i; + int current = 0; + bool bOk; + QString error; + int argc = qApp->argc(); + char** argv = qApp->argv(); + + // 1. Check naming service + bOk = false; + for ( i = 0; i < myAttempts ; i++ ) { + QtxSplash::setStatus( info.arg( "Waiting for naming service..." ), current * myAttempts + i ); + QThread::usleep( i == 0 ? 500000 : myDelay ); + try { + CORBA::ORB_var orb = CORBA::ORB_init( argc, argv ); + CORBA::Object_var obj = orb->resolve_initial_references( "NameService" ); + CosNaming::NamingContext_var _root_context = CosNaming::NamingContext::_narrow( obj ); + if ( !CORBA::is_nil( _root_context ) ) { + bOk = true; + break; + } + } + catch( CORBA::COMM_FAILURE& ) { + MESSAGE( "CORBA::COMM_FAILURE: unable to contact the naming service" ); + } + catch( ... ) { + MESSAGE( "Unknown Exception: unable to contact the naming service" ); + } + } + if ( !bOk ) { + QtxSplash::error( "Unable to contact the naming service.\n%1" ); + return; + } + QtxSplash::setStatus( info.arg( "Waiting for naming service...OK" ), ++current * myAttempts ); + QThread::usleep( 300000 ); + + // 2. Check registry server + bOk = false; + for ( i = 0; i < myAttempts ; i++ ) { + QtxSplash::setStatus( info.arg( "Waiting for registry server..." ), current * myAttempts + i ); + QThread::usleep( i == 0 ? 500000 : myDelay ); + try { + CORBA::ORB_var orb = CORBA::ORB_init( argc, argv ); + SALOME_NamingService &NS = *SINGLETON_::Instance(); + ASSERT( SINGLETON_::IsAlreadyExisting() ); + NS.init_orb( orb ); + CORBA::Object_var obj = NS.Resolve( "/Registry" ); + Registry::Components_var registry = Registry::Components::_narrow( obj ); + if ( !CORBA::is_nil( registry ) ) { + MESSAGE( "/Registry is found" ); + registry->ping(); + MESSAGE( "Registry was activated" ); + bOk = true; + break; + } + } + catch ( ServiceUnreachable& ) { + MESSAGE( "Caught exception: Naming Service unreachable." ); + error = "Naming service unreachable"; + } + catch ( CORBA::COMM_FAILURE& ) { + MESSAGE( "Caught CORBA::SystemException CommFailure." ); + error = "Caught CORBA::SystemException CommFailure."; + } + catch ( CORBA::SystemException& ) { + MESSAGE( "Caught CORBA::SystemException." ); + error = "Caught CORBA::SystemException."; + } + catch ( CORBA::Exception& ) { + MESSAGE( "Caught CORBA::Exception." ); + error = "Caught CORBA::Exception."; + } + catch (...) { + MESSAGE( "Caught unknown exception." ); + error = "Caught unknown exception."; + } + } + if ( !bOk ) { + QtxSplash::error( QString( "Registry server is not found.\n%1" ).arg ( error ) ); + return; + } + QtxSplash::setStatus( info.arg( "Waiting for registry server...OK" ), ++current * myAttempts ); + QThread::usleep( 300000 ); + + // 3. Check data server + bOk = false; + for ( i = 0; i < myAttempts ; i++ ) { + QtxSplash::setStatus( info.arg( "Waiting for study server..." ), current * myAttempts + i ); + QThread::usleep( i == 0 ? 500000 : myDelay ); + try { + CORBA::ORB_var orb = CORBA::ORB_init( argc, argv ); + SALOME_NamingService &NS = *SINGLETON_::Instance(); + ASSERT( SINGLETON_::IsAlreadyExisting() ); + NS.init_orb( orb ); + CORBA::Object_var obj = NS.Resolve( "/myStudyManager" ); + SALOMEDS::StudyManager_var studyManager = SALOMEDS::StudyManager::_narrow( obj ); + if ( !CORBA::is_nil( studyManager ) ) { + MESSAGE( "/myStudyManager is found" ); + studyManager->ping(); + MESSAGE( "StudyManager was activated" ); + bOk = true; + break; + } + } + catch ( ServiceUnreachable& ) { + MESSAGE( "Caught exception: Naming Service unreachable." ); + error = "Naming service unreachable"; + } + catch ( CORBA::COMM_FAILURE& ) { + MESSAGE( "Caught CORBA::SystemException CommFailure." ); + error = "Caught CORBA::SystemException CommFailure."; + } + catch ( CORBA::SystemException& ) { + MESSAGE( "Caught CORBA::SystemException." ); + error = "Caught CORBA::SystemException."; + } + catch ( CORBA::Exception& ) { + MESSAGE( "Caught CORBA::Exception." ); + error = "Caught CORBA::Exception."; + } + catch (...) { + MESSAGE( "Caught unknown exception." ); + error = "Caught unknown exception."; + } + } + if ( !bOk ) { + QtxSplash::error( QString( "Study server is not found.\n%1" ).arg ( error ) ); + return; + } + QtxSplash::setStatus( info.arg( "Waiting for study server...OK" ), ++current * myAttempts ); + QThread::usleep( 300000 ); + + // 4. Check module catalogue server + bOk = false; + for ( i = 0; i < myAttempts ; i++ ) { + QtxSplash::setStatus( info.arg( "Waiting for module catalogue server..." ), current * myAttempts + i ); + QThread::usleep( i == 0 ? 500000 : myDelay ); + try { + CORBA::ORB_var orb = CORBA::ORB_init( argc, argv ); + SALOME_NamingService &NS = *SINGLETON_::Instance(); + ASSERT( SINGLETON_::IsAlreadyExisting() ); + NS.init_orb( orb ); + CORBA::Object_var obj = NS.Resolve( "/Kernel/ModulCatalog" ); + SALOME_ModuleCatalog::ModuleCatalog_var catalog = SALOME_ModuleCatalog::ModuleCatalog::_narrow( obj ); + if ( !CORBA::is_nil( catalog ) ){ + MESSAGE( "/Kernel/ModulCatalog is found" ); + catalog->ping(); + MESSAGE( "ModuleCatalog was activated" ); + bOk = true; + break; + } + } + catch ( ServiceUnreachable& ) { + MESSAGE( "Caught exception: Naming Service unreachable." ); + error = "Naming service unreachable"; + } + catch ( CORBA::COMM_FAILURE& ) { + MESSAGE( "Caught CORBA::SystemException CommFailure." ); + error = "Caught CORBA::SystemException CommFailure."; + } + catch ( CORBA::SystemException& ) { + MESSAGE( "Caught CORBA::SystemException." ); + error = "Caught CORBA::SystemException."; + } + catch ( CORBA::Exception& ) { + MESSAGE( "Caught CORBA::Exception." ); + error = "Caught CORBA::Exception."; + } + catch (...) { + MESSAGE( "Caught unknown exception." ); + error = "Caught unknown exception."; + } + } + if ( !bOk ) { + QtxSplash::error( QString( "Module catalogue server is not found.\n%1" ).arg ( error ) ); + return; + } + QtxSplash::setStatus( info.arg( "Waiting for module catalogue server...OK" ), ++current * myAttempts ); + QThread::usleep( 300000 ); + + // 5. Check data server + bOk = false; + for ( i = 0; i < myAttempts ; i++ ) { + QtxSplash::setStatus( info.arg( "Waiting for session server..." ), current * myAttempts + i ); + QThread::usleep( i == 0 ? 500000 : myDelay ); + try { + CORBA::ORB_var orb = CORBA::ORB_init( argc, argv ); + SALOME_NamingService &NS = *SINGLETON_::Instance(); + ASSERT( SINGLETON_::IsAlreadyExisting() ); + NS.init_orb( orb ); + CORBA::Object_var obj = NS.Resolve( "/Kernel/Session" ); + SALOME::Session_var session = SALOME::Session::_narrow( obj ); + if ( !CORBA::is_nil( session ) ) { + MESSAGE( "/Kernel/Session is found" ); + session->ping(); + MESSAGE( "SALOME_Session was activated" ); + bOk = true; + break; + } + } + catch ( ServiceUnreachable& ) { + MESSAGE( "Caught exception: Naming Service unreachable." ); + error = "Naming service unreachable"; + } + catch ( CORBA::COMM_FAILURE& ) { + MESSAGE( "Caught CORBA::SystemException CommFailure." ); + error = "Caught CORBA::SystemException CommFailure."; + } + catch ( CORBA::SystemException& ) { + MESSAGE( "Caught CORBA::SystemException." ); + error = "Caught CORBA::SystemException."; + } + catch ( CORBA::Exception& ) { + MESSAGE( "Caught CORBA::Exception." ); + error = "Caught CORBA::Exception."; + } + catch (...) { + MESSAGE( "Caught unknown exception." ); + error = "Caught unknown exception."; + } + } + if ( !bOk ) { + QtxSplash::error( QString( "Session server is not found.\n%1" ).arg ( error ) ); + return; + } + QtxSplash::setStatus( info.arg( "Waiting for session server...OK" ), ++current * myAttempts ); + QThread::usleep( 300000 ); + + // 6. Check C++ container + if ( myCheckCppContainer ) { + bOk = false; + for ( i = 0; i < myAttempts ; i++ ) { + QtxSplash::setStatus( info.arg( "Waiting for C++ container..." ), current * myAttempts + i ); + QThread::usleep( i == 0 ? 500000 : myDelay ); + try { + CORBA::ORB_var orb = CORBA::ORB_init( argc, argv ); + SALOME_NamingService &NS = *SINGLETON_::Instance(); + ASSERT( SINGLETON_::IsAlreadyExisting() ); + NS.init_orb( orb ); + QString containerName = QString( "/Containers/%1/FactoryServer" ).arg( GetHostname() ); + CORBA::Object_var obj = NS.Resolve( containerName.latin1() ); + Engines::Container_var FScontainer = Engines::Container::_narrow( obj ); + if ( !CORBA::is_nil( FScontainer ) ) { + MESSAGE( containerName.latin1() << " is found" ); + FScontainer->ping(); + MESSAGE( "FactoryServer container was activated" ); + bOk = true; + break; + } + } + catch ( ServiceUnreachable& ) { + MESSAGE( "Caught exception: Naming Service unreachable." ); + error = "Naming service unreachable"; + } + catch ( CORBA::COMM_FAILURE& ) { + MESSAGE( "Caught CORBA::SystemException CommFailure." ); + error = "Caught CORBA::SystemException CommFailure."; + } + catch ( CORBA::SystemException& ) { + MESSAGE( "Caught CORBA::SystemException." ); + error = "Caught CORBA::SystemException."; + } + catch ( CORBA::Exception& ) { + MESSAGE( "Caught CORBA::Exception." ); + error = "Caught CORBA::Exception."; + } + catch (...) { + MESSAGE( "Caught unknown exception." ); + error = "Caught unknown exception."; + } + } + if ( !bOk ) { + QtxSplash::error( QString( "C++ container is not found.\n%1" ).arg ( error ) ); + return; + } + QtxSplash::setStatus( info.arg( "Waiting for C++ container...OK" ), ++current * myAttempts ); + QThread::usleep( 300000 ); + } + + // 7. Check Python container + if ( myCheckPyContainer ) { + bOk = false; + for ( i = 0; i < myAttempts ; i++ ) { + QtxSplash::setStatus( info.arg( "Waiting for Python container..." ), current * myAttempts + i ); + QThread::usleep( i == 0 ? 500000 : myDelay ); + try { + CORBA::ORB_var orb = CORBA::ORB_init( argc, argv ); + SALOME_NamingService &NS = *SINGLETON_::Instance(); + ASSERT( SINGLETON_::IsAlreadyExisting() ); + NS.init_orb( orb ); + QString containerName = QString( "/Containers/%1/FactoryServerPy" ).arg( GetHostname() ); + CORBA::Object_var obj = NS.Resolve( containerName.latin1() ); + Engines::Container_var FSPcontainer = Engines::Container::_narrow( obj ); + if ( !CORBA::is_nil( FSPcontainer ) ) { + MESSAGE( containerName.latin1() << " is found" ); + FSPcontainer->ping(); + MESSAGE("FactoryServerPy container was activated"); + bOk = true; + break; + } + } + catch ( ServiceUnreachable& ) { + MESSAGE( "Caught exception: Naming Service unreachable." ); + error = "Naming service unreachable"; + } + catch ( CORBA::COMM_FAILURE& ) { + MESSAGE( "Caught CORBA::SystemException CommFailure." ); + error = "Caught CORBA::SystemException CommFailure."; + } + catch ( CORBA::SystemException& ) { + MESSAGE( "Caught CORBA::SystemException." ); + error = "Caught CORBA::SystemException."; + } + catch ( CORBA::Exception& ) { + MESSAGE( "Caught CORBA::Exception." ); + error = "Caught CORBA::Exception."; + } + catch (...) { + MESSAGE( "Caught unknown exception." ); + error = "Caught unknown exception."; + } + } + if ( !bOk ) { + QtxSplash::error( QString( "Python container is not found.\n%1" ).arg ( error ) ); + return; + } + QtxSplash::setStatus( info.arg( "Waiting for Python container...OK" ), ++current * myAttempts ); + QThread::usleep( 300000 ); + } + + // 8. Check supervision container + if ( myCheckSVContainer ) { + bOk = false; + for ( i = 0; i < myAttempts ; i++ ) { + QtxSplash::setStatus( info.arg( "Waiting for Supervision container..." ), current * myAttempts + i ); + QThread::usleep( i == 0 ? 500000 : myDelay ); + try { + CORBA::ORB_var orb = CORBA::ORB_init( argc, argv ); + SALOME_NamingService &NS = *SINGLETON_::Instance(); + ASSERT( SINGLETON_::IsAlreadyExisting() ); + NS.init_orb( orb ); + QString containerName = QString( "/Containers/%1/SuperVisionContainer" ).arg( GetHostname() ); + CORBA::Object_var obj = NS.Resolve( containerName.latin1() ); + Engines::Container_var SVcontainer = Engines::Container::_narrow( obj ); + if ( !CORBA::is_nil( SVcontainer ) ) { + MESSAGE( containerName.latin1() << " is found" ); + SVcontainer->ping(); + MESSAGE("SuperVisionContainer container was activated"); + bOk = true; + break; + } + } + catch ( ServiceUnreachable& ) { + MESSAGE( "Caught exception: Naming Service unreachable." ); + error = "Naming service unreachable"; + } + catch ( CORBA::COMM_FAILURE& ) { + MESSAGE( "Caught CORBA::SystemException CommFailure." ); + error = "Caught CORBA::SystemException CommFailure."; + } + catch ( CORBA::SystemException& ) { + MESSAGE( "Caught CORBA::SystemException." ); + error = "Caught CORBA::SystemException."; + } + catch ( CORBA::Exception& ) { + MESSAGE( "Caught CORBA::Exception." ); + error = "Caught CORBA::Exception."; + } + catch (...) { + MESSAGE( "Caught unknown exception." ); + error = "Caught unknown exception."; + } + } + if ( !bOk ) { + QtxSplash::error( QString( "Supervision container is not found.\n%1" ).arg ( error ) ); + return; + } + QtxSplash::setStatus( info.arg( "Waiting for Supervision container...OK" ), ++current * myAttempts ); + QThread::usleep( 300000 ); + } + // clear splash status + splash->setProgress( 0, 0 ); + splash->setStatus( initialInfo ); +} diff --git a/src/Session/Session_ServerCheck.hxx b/src/Session/Session_ServerCheck.hxx new file mode 100644 index 000000000..e4d7a83d4 --- /dev/null +++ b/src/Session/Session_ServerCheck.hxx @@ -0,0 +1,62 @@ +// Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ +// +// File: Session_ServerCheck.hxx +// Author: Vadim SANDLER + +#if !defined(SESSION_SERVERCHECK_HXX) +#define SESSION_SERVERCHECK_HXX + +#ifdef WNT +#include +#else +#define SALOME_WNT_EXPORT +#endif + +#include +#include + +class QMutex; +class QWaitCondition; + +/*! + Class Session_ServerCheck : check SALOME servers +*/ +class SALOME_WNT_EXPORT Session_ServerCheck : public QThread +{ +public: + // constructor + Session_ServerCheck( QMutex*, QWaitCondition* ); + // destructor + virtual ~Session_ServerCheck(); + + // thread loop + virtual void run() ; + +private: + QMutex* myMutex; // splash mutex + QWaitCondition* myWC; // splash wait condition + + bool myCheckCppContainer; // flag : check C++ container ? + bool myCheckPyContainer; // flag : check Python container ? + bool myCheckSVContainer; // flag : check supervision container ? + int myAttempts; // number of checks attemtps to get response from server + int myDelay; // delay between two attempts in microseconds +}; + +#endif diff --git a/src/Session/Session_ServerLauncher.cxx b/src/Session/Session_ServerLauncher.cxx index b15f682a5..9cfd7b7cf 100755 --- a/src/Session/Session_ServerLauncher.cxx +++ b/src/Session/Session_ServerLauncher.cxx @@ -54,6 +54,7 @@ Session_ServerLauncher::Session_ServerLauncher(int argc, PortableServer::POA_ptr poa, QMutex *GUIMutex, QWaitCondition *ServerLaunch, + QMutex *SessionMutex, QWaitCondition *SessionStarted) { _argc = argc; @@ -62,7 +63,11 @@ Session_ServerLauncher::Session_ServerLauncher(int argc, _root_poa = PortableServer::POA::_duplicate(poa); _GUIMutex = GUIMutex; _ServerLaunch = ServerLaunch; + _SessionMutex = SessionMutex; _SessionStarted = SessionStarted; + + // start thread + start(); } //============================================================================= @@ -83,16 +88,27 @@ Session_ServerLauncher::~Session_ServerLauncher() void Session_ServerLauncher::run() { - _GUIMutex->lock(); // lock released by calling thread when ready: wait(mutex) - _GUIMutex->unlock(); + // wait until main thread is ready + _GUIMutex->lock(); // ... lock mutex (it is unlocked my calling thread + // wait condition's wait(mutex) + _GUIMutex->unlock(); // ... and unlock it 'cause it is not more needed + + // wake main thread _ServerLaunch->wakeAll(); CheckArgs(); ActivateAll(); - _SessionStarted->wakeAll(); // wake main thread + // wait until main thread is ready + _GUIMutex->lock(); // ... lock mutex (it is unlocked my calling thread + // wait condition's wait(mutex) + _GUIMutex->unlock(); // ... and unlock it 'cause it is not more needed + + // wake main thread + _ServerLaunch->wakeAll(); - _orb->run(); // this thread wait, during omniORB process events + // run ORB + _orb->run(); // this thread waits, during omniORB process events } //============================================================================= @@ -201,7 +217,7 @@ void Session_ServerLauncher::ActivateAll() std::cout << "*** activating [" << argc << "] : " << argv[0] << std::endl; Session_ServerThread* aServerThread - = new Session_ServerThread(argc, argv, _orb,_root_poa,_GUIMutex); + = new Session_ServerThread(argc, argv, _orb,_root_poa); _serverThreads.push_front(aServerThread); aServerThread->Init(); @@ -214,7 +230,7 @@ void Session_ServerLauncher::ActivateAll() char** argv = new char*[argc]; argv[0] = "Session"; Session_SessionThread* aServerThread - = new Session_SessionThread(argc, argv, _orb,_root_poa,_GUIMutex,_ServerLaunch); + = new Session_SessionThread(argc, argv, _orb,_root_poa,_SessionMutex,_SessionStarted); _serverThreads.push_front(aServerThread); aServerThread->Init(); diff --git a/src/Session/Session_ServerLauncher.hxx b/src/Session/Session_ServerLauncher.hxx index 8791b6698..7c97199fe 100755 --- a/src/Session/Session_ServerLauncher.hxx +++ b/src/Session/Session_ServerLauncher.hxx @@ -70,6 +70,7 @@ public: PortableServer::POA_ptr poa, QMutex *GUIMutex, QWaitCondition *ServerLaunch, + QMutex *SessionMutex, QWaitCondition *SessionStarted); virtual ~Session_ServerLauncher(); void run(); @@ -82,13 +83,14 @@ protected: private: int _argc; char ** _argv; - CORBA::ORB_var _orb; - PortableServer::POA_var _root_poa; - QMutex* _GUIMutex; - QWaitCondition *_ServerLaunch; - QWaitCondition *_SessionStarted; - list _argServToLaunch; - vector _argCopy; + CORBA::ORB_var _orb; + PortableServer::POA_var _root_poa; + QMutex* _GUIMutex; + QWaitCondition* _ServerLaunch; + QMutex* _SessionMutex; + QWaitCondition* _SessionStarted; + list _argServToLaunch; + vector _argCopy; list _serverThreads; }; diff --git a/src/Session/Session_ServerThread.cxx b/src/Session/Session_ServerThread.cxx index a0d00d9ea..8cec46993 100755 --- a/src/Session/Session_ServerThread.cxx +++ b/src/Session/Session_ServerThread.cxx @@ -82,15 +82,13 @@ Session_ServerThread::Session_ServerThread() Session_ServerThread::Session_ServerThread(int argc, char ** argv, CORBA::ORB_ptr orb, - PortableServer::POA_ptr poa, - QMutex *GUIMutex) + PortableServer::POA_ptr poa) { //MESSAGE("Session_ServerThread Constructor " << argv[0]); _argc = argc; _argv = argv; _orb = CORBA::ORB::_duplicate(orb); _root_poa = PortableServer::POA::_duplicate(poa); - _GUIMutex = GUIMutex; _servType =-1; _NS = new SALOME_NamingService(_orb); // one instance per server to limit // multi thread coherence problems @@ -511,7 +509,8 @@ Session_SessionThread::Session_SessionThread(int argc, PortableServer::POA_ptr poa, QMutex* GUIMutex, QWaitCondition* GUILauncher) -: Session_ServerThread(argc, argv, orb, poa, GUIMutex), +: Session_ServerThread(argc, argv, orb, poa), + _GUIMutex( GUIMutex ), _GUILauncher( GUILauncher ) { } diff --git a/src/Session/Session_ServerThread.hxx b/src/Session/Session_ServerThread.hxx index a10ab0ce6..de87612ed 100755 --- a/src/Session/Session_ServerThread.hxx +++ b/src/Session/Session_ServerThread.hxx @@ -50,8 +50,7 @@ public: Session_ServerThread(int argc, char ** argv, CORBA::ORB_ptr orb, - PortableServer::POA_ptr poa, - QMutex *GUIMutex); + PortableServer::POA_ptr poa); virtual ~Session_ServerThread(); void Init(); protected: @@ -68,7 +67,6 @@ protected: int _servType; CORBA::ORB_var _orb; PortableServer::POA_var _root_poa; - QMutex* _GUIMutex; SALOME_NamingService * _NS; }; @@ -88,6 +86,7 @@ public: protected: virtual void ActivateSession ( int argc, char ** argv ); private: + QMutex* _GUIMutex; QWaitCondition* _GUILauncher; }; -- 2.39.2