//
#include "Session_ServerCheck.hxx"
-#include <QtxSplash.h>
#include <SALOMEconfig.h>
#include CORBA_CLIENT_HEADER(SALOME_Session)
#include "utilities.h"
#include <QApplication>
-#include <QMutex>
#include <QWaitCondition>
+#include <QMutexLocker>
+#include <QStringList>
+//
// 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
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
}
/*!
- 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;
}
}
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_<SALOME_NamingService>::Instance();
MESSAGE( "/Registry is found" );
registry->ping();
MESSAGE( "Registry was activated" );
- bOk = true;
+ setStep( ++current * myAttempts );
break;
}
}
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_<SALOME_NamingService>::Instance();
MESSAGE( "/myStudyManager is found" );
studyManager->ping();
MESSAGE( "StudyManager was activated" );
- bOk = true;
+ setStep( ++current * myAttempts );
break;
}
}
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_<SALOME_NamingService>::Instance();
MESSAGE( "/Kernel/ModulCatalog is found" );
catalog->ping();
MESSAGE( "ModuleCatalog was activated" );
- bOk = true;
+ setStep( ++current * myAttempts );
break;
}
}
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_<SALOME_NamingService>::Instance();
MESSAGE( "/Kernel/Session is found" );
session->ping();
MESSAGE( "SALOME_Session was activated" );
- bOk = true;
+ setStep( ++current * myAttempts );
break;
}
}
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_<SALOME_NamingService>::Instance();
MESSAGE( containerName.toLatin1().constData() << " is found" );
FScontainer->ping();
MESSAGE( "FactoryServer container was activated" );
- bOk = true;
+ setStep( ++current * myAttempts );
break;
}
}
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_<SALOME_NamingService>::Instance();
MESSAGE( containerName.toLatin1().constData() << " is found" );
FSPcontainer->ping();
MESSAGE("FactoryServerPy container was activated");
- bOk = true;
+ setStep( ++current * myAttempts );
break;
}
}
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_<SALOME_NamingService>::Instance();
MESSAGE( containerName.toLatin1().constData() << " is found" );
SVcontainer->ping();
MESSAGE("SuperVisionContainer container was activated");
- bOk = true;
+ setStep( ++current * myAttempts );
break;
}
}
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 );
}