From cd301ffd76645ff74e1a1ec338bc0289d3552444 Mon Sep 17 00:00:00 2001 From: vsr Date: Wed, 11 Jul 2007 11:16:16 +0000 Subject: [PATCH] *** empty log message *** --- src/Session/SALOME_Session_Server.cxx | 33 ++- src/Session/Session_ServerCheck.cxx | 408 ++++++++++++++++---------- src/Session/Session_ServerCheck.hxx | 49 ++-- 3 files changed, 315 insertions(+), 175 deletions(-) diff --git a/src/Session/SALOME_Session_Server.cxx b/src/Session/SALOME_Session_Server.cxx index acfb2ebfb..78caf6a05 100755 --- a/src/Session/SALOME_Session_Server.cxx +++ b/src/Session/SALOME_Session_Server.cxx @@ -305,7 +305,6 @@ int main( int argc, char **argv ) // 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" ) ); @@ -367,7 +366,7 @@ int main( int argc, char **argv ) splashInfo.replace( QRegExp( "%L" ), QObject::tr( "ABOUT_LICENSE" ) ); splashInfo.replace( QRegExp( "%C" ), QObject::tr( "ABOUT_COPYRIGHT" ) ); splashInfo.replace( QRegExp( "\\\\n" ), "\n" ); - splash->message( splashInfo ); + splash->setConstantInfo( splashInfo ); } // ...set 'hide on click' flag #ifdef _DEBUG_ @@ -375,7 +374,7 @@ int main( int argc, char **argv ) #endif // ...show splash splash->show(); - qApp->processEvents(); + QApplication::instance()->processEvents(); } } @@ -467,14 +466,29 @@ int main( int argc, char **argv ) _SplashMutex.lock(); // ...create servers checking thread Session_ServerCheck sc( &_SplashMutex, &_SplashStarted ); - // ...block this thread until servers checking is finished - _SplashStarted.wait( &_SplashMutex ); + // ... set initial progress + splash->setProgress( 0, sc.totalSteps() ); + // start check loop + while ( true ) { + int step = sc.currentStep(); + int total = sc.totalSteps(); + QString msg = sc.currentMessage(); + QString err = sc.error(); + if ( !err.isEmpty() ) { + QtxSplash::error( err ); + QApplication::instance()->processEvents(); + result = -1; + break; + } + QtxSplash::setStatus( msg, step ); + QApplication::instance()->processEvents(); + if ( step >= total ) + break; + // ...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..." ) ); } // Finalize embedded servers launcher @@ -487,6 +501,7 @@ int main( int argc, char **argv ) if ( !result ) { // Launch GUI activator if ( isGUI ) { + splash->setStatus( QApplication::translate( "", "Activating desktop..." ) ); // ...retrieve Session interface reference CORBA::Object_var obj = _NS->Resolve( "/Kernel/Session" ); SALOME::Session_var session = SALOME::Session::_narrow( obj ) ; diff --git a/src/Session/Session_ServerCheck.cxx b/src/Session/Session_ServerCheck.cxx index 3661b8714..d037a5b76 100644 --- a/src/Session/Session_ServerCheck.cxx +++ b/src/Session/Session_ServerCheck.cxx @@ -21,7 +21,6 @@ // #include "Session_ServerCheck.hxx" -#include #include #include CORBA_CLIENT_HEADER(SALOME_Session) @@ -37,29 +36,102 @@ #include "utilities.h" #include -#include #include +#include +#include +// // Default settings -const int __DEFAULT__ATTEMPTS__ = 300; // number of checks attemtps - // can be overrided by CSF_RepeatServerRequest - // environment variable -const int __DEFAULT__DELAY__ = 50000; // delay between attempts (microseconds) - // can be overrided by CSF_DelayServerRequest - // environment variable +// + +/*! + \brief Default number of attemtps to check SALOME server. + + This value can be changed by setting the CSF_RepeatServerRequest + environment variable. For example, to set number of check attempts + for each server to 1000: + \code + setenv CSF_RepeatServerRequest 1000 + \endcode +*/ +const int __DEFAULT__ATTEMPTS__ = 300; + +/*! + \brief Default delay between attempts (in microseconds). + + This value can be changed by setting the CSF_DelayServerRequest + environment variable. For example, to set delay between attemtps + to check SALOME servers to 100000 (0.1 second): + \code + setenv CSF_DelayServerRequest 100000 + \endcode +*/ +const int __DEFAULT__DELAY__ = 50000; + +/*! + \classSession_ServerCheck::Locker + \brief Automatic locker/unlocker. + \internal +*/ + +class Session_ServerCheck::Locker +{ +public: + /*! + \brief Constructor. Tries to aquire lock. + */ + Locker( Session_ServerCheck* sc ) + : myChecker( sc ) + { + myChecker->myMutex->lock(); + myChecker->myMutex->unlock(); + } + /*! + \brief Destructor. Wakes the calling thread and goes sleeping. + */ + ~Locker() + { + myChecker->myWC->wakeAll(); + myChecker->usleep( myChecker->myDelay ); + } +private: + Session_ServerCheck* myChecker; +}; /*! - Constructor + \class Session_ServerCheck + \brief The class Session_ServerCheck is used to check SALOME + servers availability. + + It runs in the secondrary thread. The number of attemts to check + each SALOME server and the time delay between checks can be specified + via setting the CSF_RepeatServerRequest and CSF_DelayServerRequest + environment variables. + + Total number of the check attempts can be retrieved via totalSteps() + method and current check step can be retrieved via currentStep() method. + + The method currentMessage() can be used to get the information message + about what SALOME server is currently checked. If any error occured (some + server could not be found) the thread loop is stopped and error status + is set. Error message can be retrieved with the error() method. +*/ + +/*! + \brief Constructor. + \param mutex a mutex used to serialize progress operations (splash) + \param wc a wait condition used in combination with \a mutex */ 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__ ) +: QThread(), + myMutex( mutex ), + myWC( wc ), + myCheckCppContainer( false ), + myCheckPyContainer( false ), + myCheckSVContainer( false ), + myAttempts( __DEFAULT__ATTEMPTS__ ), + myDelay ( __DEFAULT__DELAY__ ), + myCurrentStep( 0 ) { char* cenv; // try to get nb of attempts from environment variable @@ -69,14 +141,12 @@ Session_ServerCheck::Session_ServerCheck( QMutex* mutex, QWaitCondition* wc ) 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; + // parse command line check if it is necessary to wait SALOME containers + QStringList args = QApplication::arguments(); + for ( int i = 1; i < args.count(); i++ ) { + myCheckCppContainer = myCheckCppContainer || args[i] == "CPP"; + myCheckPyContainer = myCheckPyContainer || args[i] == "PY"; + myCheckSVContainer = myCheckSVContainer || args[i] == "SUPERV"; } // start thread @@ -84,69 +154,114 @@ Session_ServerCheck::Session_ServerCheck( QMutex* mutex, QWaitCondition* wc ) } /*! - Destructor + \brief Destructor */ Session_ServerCheck::~Session_ServerCheck() { } /*! - Thread loop. Checnk SALOME servers and shows status message - in the splash screen. + \brief Get current information message. + \return current message */ -void Session_ServerCheck::run() +QString Session_ServerCheck::currentMessage() { - // 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(); - } - }; + static QStringList messages; + if ( messages.isEmpty() ) { + messages << tr( "Waiting for naming service..." ); + messages << tr( "Waiting for registry server..." ); + messages << tr( "Waiting for study server..." ); + messages << tr( "Waiting for module catalogue server..." ); + messages << tr( "Waiting for session server..." ); + messages << tr( "Waiting for C++ container..." ); + messages << tr( "Waiting for Python container..." ); + messages << tr( "Waiting for Supervision container..." ); + } + QMutexLocker locker( &myDataMutex ); + QString msg; + int idx = myCurrentStep / myAttempts; + if ( idx >= 0 && idx < messages.count() ) + msg = messages[ idx ]; + return msg; +} - // lock mutex (ensure splash is shown) - Locker locker( myMutex, myWC ); +/*! + \brief Get error message. + \return error message or null string of there was no any error +*/ +QString Session_ServerCheck::error() +{ + QMutexLocker locker( &myDataMutex ); + return myError; +} - // set initial splash status - QtxSplash* splash = QtxSplash::splash(); +/*! + \brief Get current step. + \return current step +*/ +int Session_ServerCheck::currentStep() +{ + QMutexLocker locker( &myDataMutex ); + return myCurrentStep; +} +/*! + \brief Get total number of check steps. + \return total number of steps +*/ +int Session_ServerCheck::totalSteps() +{ + QMutexLocker locker( &myDataMutex ); int cnt = 5; // base servers if ( myCheckCppContainer ) cnt++; // + C++ container if ( myCheckPyContainer ) cnt++; // + Python container if ( myCheckSVContainer ) cnt++; // + supervision container + return cnt * myAttempts; +} - splash->setProgress( 0, cnt * myAttempts ); - QString initialInfo = splash->message(); - QString info = initialInfo.isEmpty() ? "%1" : QString( "%1\n%2" ).arg( initialInfo ); +/*! + \brief Modify current step. + \param step new current step value +*/ +void Session_ServerCheck::setStep( const int step ) +{ + QMutexLocker locker( &myDataMutex ); + myCurrentStep = step; +} + +/*! + \brief Set error message. + \param msg error message +*/ +void Session_ServerCheck::setError( const QString& msg ) +{ + QMutexLocker locker( &myDataMutex ); + myError = msg; +} +/*! + \brief Thread loop function. Performs SALOME servers check. +*/ +void Session_ServerCheck::run() +{ // start check servers - int i; int current = 0; - bool bOk; QString error; - int argc = qApp->argc(); - char** argv = qApp->argv(); + int argc = QApplication::instance()->argc(); + char** argv = QApplication::instance()->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 ? 50000 : myDelay ); + for ( int i = 0; i < myAttempts; i++ ) { + Locker locker( this ); + + setStep( current * myAttempts + i ); + 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; + setStep( ++current * myAttempts ); break; } } @@ -156,19 +271,19 @@ void Session_ServerCheck::run() catch( ... ) { MESSAGE( "Unknown Exception: unable to contact the naming service" ); } + + if ( i == myAttempts-1 ) { + setError( tr( "Unable to contact the naming service.\n" ) ); + return; + } } - 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( 30000 ); - + // 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 ? 50000 : myDelay ); + for ( int i = 0; i < myAttempts ; i++ ) { + Locker locker( this ); + + setStep( current * myAttempts + i ); + try { CORBA::ORB_var orb = CORBA::ORB_init( argc, argv ); SALOME_NamingService &NS = *SINGLETON_::Instance(); @@ -180,7 +295,7 @@ void Session_ServerCheck::run() MESSAGE( "/Registry is found" ); registry->ping(); MESSAGE( "Registry was activated" ); - bOk = true; + setStep( ++current * myAttempts ); break; } } @@ -204,19 +319,19 @@ void Session_ServerCheck::run() MESSAGE( "Caught unknown exception." ); error = "Caught unknown exception."; } + + if ( i == myAttempts-1 ) { + setError( tr( "Registry server is not found.\n%1" ).arg ( error ) ); + return; + } } - 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( 30000 ); // 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 ? 50000 : myDelay ); + for ( int i = 0; i < myAttempts ; i++ ) { + Locker locker( this ); + + setStep( current * myAttempts + i ); + try { CORBA::ORB_var orb = CORBA::ORB_init( argc, argv ); SALOME_NamingService &NS = *SINGLETON_::Instance(); @@ -228,7 +343,7 @@ void Session_ServerCheck::run() MESSAGE( "/myStudyManager is found" ); studyManager->ping(); MESSAGE( "StudyManager was activated" ); - bOk = true; + setStep( ++current * myAttempts ); break; } } @@ -252,19 +367,19 @@ void Session_ServerCheck::run() 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( 30000 ); + if ( i == myAttempts-1 ) { + setError( tr( "Study server is not found.\n%1" ).arg ( error ) ); + return; + } + } + // 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 ? 50000 : myDelay ); + for ( int i = 0; i < myAttempts ; i++ ) { + Locker locker( this ); + + setStep( current * myAttempts + i ); + try { CORBA::ORB_var orb = CORBA::ORB_init( argc, argv ); SALOME_NamingService &NS = *SINGLETON_::Instance(); @@ -276,7 +391,7 @@ void Session_ServerCheck::run() MESSAGE( "/Kernel/ModulCatalog is found" ); catalog->ping(); MESSAGE( "ModuleCatalog was activated" ); - bOk = true; + setStep( ++current * myAttempts ); break; } } @@ -300,19 +415,19 @@ void Session_ServerCheck::run() MESSAGE( "Caught unknown exception." ); error = "Caught unknown exception."; } + + if ( i == myAttempts-1 ) { + setError( tr( "Module catalogue server is not found.\n%1" ).arg ( error ) ); + return; + } } - 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( 30000 ); // 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 ? 50000 : myDelay ); + for ( int i = 0; i < myAttempts ; i++ ) { + Locker locker( this ); + + setStep( current * myAttempts + i ); + try { CORBA::ORB_var orb = CORBA::ORB_init( argc, argv ); SALOME_NamingService &NS = *SINGLETON_::Instance(); @@ -324,7 +439,7 @@ void Session_ServerCheck::run() MESSAGE( "/Kernel/Session is found" ); session->ping(); MESSAGE( "SALOME_Session was activated" ); - bOk = true; + setStep( ++current * myAttempts ); break; } } @@ -348,20 +463,20 @@ void Session_ServerCheck::run() MESSAGE( "Caught unknown exception." ); error = "Caught unknown exception."; } + + if ( i == myAttempts-1 ) { + setError( tr( "Session server is not found.\n%1" ).arg ( error ) ); + return; + } } - 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( 30000 ); // 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 ? 50000 : myDelay ); + for ( int i = 0; i < myAttempts ; i++ ) { + Locker locker( this ); + + setStep( current * myAttempts + i ); + try { CORBA::ORB_var orb = CORBA::ORB_init( argc, argv ); SALOME_NamingService &NS = *SINGLETON_::Instance(); @@ -374,7 +489,7 @@ void Session_ServerCheck::run() MESSAGE( containerName.toLatin1().constData() << " is found" ); FScontainer->ping(); MESSAGE( "FactoryServer container was activated" ); - bOk = true; + setStep( ++current * myAttempts ); break; } } @@ -398,21 +513,21 @@ void Session_ServerCheck::run() MESSAGE( "Caught unknown exception." ); error = "Caught unknown exception."; } + + if ( i == myAttempts-1 ) { + setError( tr( "C++ container is not found.\n%1" ).arg ( error ) ); + return; + } } - 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( 30000 ); } // 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 ? 50000 : myDelay ); + for ( int i = 0; i < myAttempts ; i++ ) { + Locker locker( this ); + + setStep( current * myAttempts + i ); + try { CORBA::ORB_var orb = CORBA::ORB_init( argc, argv ); SALOME_NamingService &NS = *SINGLETON_::Instance(); @@ -425,7 +540,7 @@ void Session_ServerCheck::run() MESSAGE( containerName.toLatin1().constData() << " is found" ); FSPcontainer->ping(); MESSAGE("FactoryServerPy container was activated"); - bOk = true; + setStep( ++current * myAttempts ); break; } } @@ -449,21 +564,21 @@ void Session_ServerCheck::run() MESSAGE( "Caught unknown exception." ); error = "Caught unknown exception."; } + + if ( i == myAttempts-1 ) { + setError( tr( "Python container is not found.\n%1" ).arg ( error ) ); + return; + } } - 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( 30000 ); } // 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 ? 50000 : myDelay ); + for ( int i = 0; i < myAttempts ; i++ ) { + Locker locker( this ); + + setStep( current * myAttempts + i ); + try { CORBA::ORB_var orb = CORBA::ORB_init( argc, argv ); SALOME_NamingService &NS = *SINGLETON_::Instance(); @@ -476,7 +591,7 @@ void Session_ServerCheck::run() MESSAGE( containerName.toLatin1().constData() << " is found" ); SVcontainer->ping(); MESSAGE("SuperVisionContainer container was activated"); - bOk = true; + setStep( ++current * myAttempts ); break; } } @@ -500,14 +615,11 @@ void Session_ServerCheck::run() MESSAGE( "Caught unknown exception." ); error = "Caught unknown exception."; } + + if ( i == myAttempts-1 ) { + setError( tr( "Supervision container is not found.\n%1" ).arg ( error ) ); + return; + } } - 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( 30000 ); } - // clear splash status - splash->setStatus( initialInfo ); } diff --git a/src/Session/Session_ServerCheck.hxx b/src/Session/Session_ServerCheck.hxx index 35faf4d38..07c007113 100644 --- a/src/Session/Session_ServerCheck.hxx +++ b/src/Session/Session_ServerCheck.hxx @@ -23,36 +23,49 @@ #if !defined(SESSION_SERVERCHECK_HXX) #define SESSION_SERVERCHECK_HXX -#include +#include "SALOME_Session.hxx" #include +#include -class QMutex; class QWaitCondition; -/*! - Class Session_ServerCheck : check SALOME servers -*/ class SESSION_EXPORT Session_ServerCheck : public QThread { + class Locker; + public: - // constructor Session_ServerCheck( QMutex*, QWaitCondition* ); - // destructor virtual ~Session_ServerCheck(); - // thread loop - virtual void run() ; + QString currentMessage(); + QString error(); + + int currentStep(); + int totalSteps(); + +protected: + 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 + void setStep( const int ); + void setError( const QString& msg ); + +private: + QMutex myDataMutex; //!< data mutex + 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 attemtps to get response from server + int myDelay; //!< delay between attempts in microseconds + int myCurrentStep; //!< current step + QString myMessage; //!< current information message + QString myError; //!< error message + + friend class Locker; }; -#endif +#endif // SESSION_SERVERCHECK_HXX -- 2.39.2