* Constructor
*/
//===========================================================
-SALOME_Event::SALOME_Event():
- myWait( true ),
- myAutoRelease( false )
-{
- if(MYDEBUG) MESSAGE( "SALOME_Event::SALOME_Event(): this = "<<this<<", myWait = "<<myWait );
- if ( myWait ) {
- // Prepare the semaphore
- mySemaphore = new QSemaphore( 2 );
- mySemaphore->operator+=( 2 );
- }
+SALOME_Event::SALOME_Event(){
+ if(MYDEBUG) MESSAGE( "SALOME_Event::SALOME_Event(): this = "<<this );
+ // Prepare the semaphore
+ mySemaphore = new QSemaphore( 2 );
+ *mySemaphore += 2;
}
//===========================================================
* Destructor
*/
//===========================================================
-SALOME_Event::~SALOME_Event()
-{
- if(MYDEBUG) MESSAGE( "SALOME_Event::~SALOME_Event(): this = "<<this<<", myWait = "<<myWait );
- if ( myWait ) {
- if ( mySemaphore->available() < mySemaphore->total() )
- mySemaphore->operator-=( mySemaphore->total() - mySemaphore->available() );
- delete mySemaphore;
- }
+SALOME_Event::~SALOME_Event(){
+ if(MYDEBUG) MESSAGE( "SALOME_Event::~SALOME_Event(): this = "<<this );
+ if ( mySemaphore->available() < mySemaphore->total() )
+ *mySemaphore -= mySemaphore->total() - mySemaphore->available();
+ delete mySemaphore;
}
//===========================================================
//===========================================================
void SALOME_Event::process()
{
- if(MYDEBUG) MESSAGE( "SALOME_Event::process(): this = "<<this<<", myWait = "<<myWait );
QThread::postEvent( qApp, new QCustomEvent( SALOME_EVENT, (void*)this ) );
- if ( myWait ) {
- if(MYDEBUG) MESSAGE( "SALOME_Event::process(): available = " << mySemaphore->available() );
- if ( !mySemaphore->available() )
- mySemaphore->operator+=( 1 );
-
- if(MYDEBUG) MESSAGE( "SALOME_Event::process() COMPLETED: this = "<<this<<", myWait = "<<myWait );
- }
- if ( myAutoRelease )
- release();
+ if(MYDEBUG) MESSAGE( "SALOME_Event::process(): this = "<<this<<", *mySemaphore += 1 " );
+ *mySemaphore += 1;
+ if(MYDEBUG) MESSAGE( "SALOME_Event::process(): this = "<<this<<" - COMPLETED" );
}
//===========================================================
//===========================================================
void SALOME_Event::processed()
{
- if(MYDEBUG) MESSAGE( "SALOME_Event::processed(): this = "<<this<<", myWait = "<<myWait );
- if ( myWait ) {
- if(MYDEBUG) MESSAGE( "SALOME_Event::processed(): available = " << mySemaphore->available() );
- if ( !mySemaphore->available() ) {
- // process() takes control over mySemaphore after the next line is executed
- mySemaphore->operator-=( 1 );
-
- if(MYDEBUG) MESSAGE( "SALOME_Event::processed(): semaphore DECREMENTED" );
-
- // Current thread will block here until process() completes
- mySemaphore->operator+=( mySemaphore->total() );
- }
- }
- if(MYDEBUG) MESSAGE( "SALOME_Event::processed() COMPLETED: this = "<<this<<", myWait = "<<myWait );
-}
-
-//===========================================================
-/*!
- * SALOME_Event::release
- * Wakes up the desktop
- */
-//===========================================================
-void SALOME_Event::release()
-{
- if(MYDEBUG) MESSAGE( "SALOME_Event::release(): this = "<<this<<", myWait = "<<myWait );
- if ( myWait ) {
- if(MYDEBUG) MESSAGE( "SALOME_Event::release(): available = " << mySemaphore->available() );
- mySemaphore->operator-=( mySemaphore->total() - mySemaphore->available() );
- }
- if(MYDEBUG) MESSAGE( "SALOME_Event::release() COMPLETED: this = "<<this<<", myWait = "<<myWait );
+ if(MYDEBUG) MESSAGE( "SALOME_Event::processed(): this = "<<this );
+ // process() takes control over mySemaphore after the next line is executed
+ *mySemaphore -= 1;
}
-
-
-
-
class QSemaphore;
+extern bool IsSessionThread();
+
//===========================================================
/*!
* Class: SALOME_Event
* no need to protect such fields with a mutex, for only one thread working with
* a SALOME_Event object is active at any moment.
*
- * It is possible to make the thread that creates SALOME_Event
- * wait until the event is processed by the component GUI, SALOME_Event
- * should be constructed with <wait> == TRUE in such a case.
- *
- * SALOME_Event objects should be created on the heap. QAD_Desktop deletes
- * these objects as soon as they have been processed.
- *
* Usage:
* - create SALOME_Event object on the heap with proper <type> and <wait> parameters.
* Components can derive their own event class from SALOME_Event
* in order to pass custom data to the event handler.
* - call process() method to post the event. Between process() and release()
* it is possible to examine fields of your custom event object.
- * - call release() method to wake up the desktop (you can also set <autoRelease>
+ * - perform delete operator on the event to wake up the desktop (you can also set <autoRelease>
* parameter to TRUE to automatically wake up desktop after process()
*
* processed() method is used by the desktop to signal that event processing
* has been completed.
*
* Caveats:
- * 1. Never create SALOME_Event with <wait> == TRUE in code that is
- * supposed to be called within main GUI thread, for this will result
- * in GUI process deadlock.
- * 2. Always call release() method after process() if you use <wait> parameters as TRUE,
- * otherwise processed() method will never return and main GUI thread will be blocked!
- * 3. Never use pointers to the event after it has been released (either by calling release()
- * or automatically by process() if <autoRelease> == TRUE) to avoid application crashes!
+ * There is no.
*/
//===========================================================
-class SALOME_Event
-{
+class SALOME_Event{
public:
SALOME_Event();
virtual ~SALOME_Event();
virtual void Execute() = 0;
void process();
- void processed();
-
- void release();
private:
- bool myWait;
- bool myAutoRelease;
+ void processed();
+ friend class QAD_Desktop;
+
QSemaphore* mySemaphore;
};
// Template function for processing events with result returing
template<class TEvent> inline typename TEvent::TResult ProcessEvent(TEvent* theEvent){
- theEvent->process();
- typename TEvent::TResult aResult = theEvent->myResult;
- theEvent->release();
+ typename TEvent::TResult aResult;
+ if(IsSessionThread()){
+ theEvent->Execute();
+ aResult = theEvent->myResult;
+ }else{
+ theEvent->process();
+ aResult = theEvent->myResult;
+ }
+ delete theEvent;
return aResult;
}
// Template function for processing events without result
inline void ProcessVoidEvent(SALOME_Event* theEvent){
- theEvent->process();
- theEvent->release();
+ if(IsSessionThread()){
+ theEvent->Execute();
+ }else{
+ theEvent->process();
+ }
+ delete theEvent;
}
*/
PyInterp_PyQt::PyInterp_PyQt(): PyInterp_base()
{
- initialize();
}
PyInterp_PyQt::~PyInterp_PyQt()
}
Py_DECREF(r);
}
-
}
else if ( e->type() == SALOME_EVENT ) {
SALOME_Event* aSE = (SALOME_Event*)((QCustomEvent*)e)->data();
- processEvent( aSE );
- // Signal the calling thread that the event has been processed
- aSE->processed();
+ processEvent(aSE);
((QCustomEvent*)e)->setData( 0 );
- delete aSE;
return TRUE;
}
return QMainWindow::eventFilter( o, e );
*/
void QAD_Desktop::processEvent( SALOME_Event* theEvent )
{
- if ( !theEvent )
- return;
- theEvent->Execute();
+ if( theEvent ){
+ theEvent->Execute();
+ // Signal the calling thread that the event has been processed
+ theEvent->processed();
+ }
}
/*!
_isInHistory = true;
_currentCommand = text(endLine).remove(0,SIZEPR);
_currentCommand.truncate( _currentCommand.length() - 1 );
- SCRUTE(_currentCommand);
}
QString previousCommand = myInterp->getPrevious();
if (previousCommand.compare(BEGIN_HISTORY_PY) != 0)
* The creation of Python interpretor must be protected par a C++ Lock because of C threads
*/
ThreadLock aPyLock = GetPyThreadLock("SALOME_PYQT_GUI::initInterp");
- interp=new PyInterp_PyQt();
+ interp = new PyInterp_PyQt();
+ interp->initialize();
mapInterp[StudyID] = interp;
}
// imports Python GUI module and puts it in _module attribute
#include <unistd.h>
using namespace std;
+#include <pthread.h>
#include <qthread.h>
#include <qapplication.h>
#include <qlabel.h>
* - get session state
*/
+#ifdef _DEBUG_
+static int MYDEBUG = 0;
+#else
+static int MYDEBUG = 0;
+#endif
+
+static pthread_t myThread;
+
+extern bool IsSessionThread(){
+ bool aResult = myThread == pthread_self();
+ if(MYDEBUG) INFOS("IsSessionThread() - "<<aResult);
+ return aResult;
+}
+
int main(int argc, char **argv)
{
try
{
+ myThread = pthread_self();
+
ORB_INIT &init = *SINGLETON_<ORB_INIT>::Instance() ;
ASSERT(SINGLETON_<ORB_INIT>::IsAlreadyExisting()) ;
int orbArgc = 1;
#include "SALOME_Session_i.hxx"
#include "SALOME_NamingService.hxx"
-#include "SALOME_Session_QThread.hxx"
#include "QAD_Application.h"
#include "QAD_Desktop.h"