1 // SALOME SALOMEGUI : implementation of desktop and GUI kernel
3 // Copyright (C) 2005 CEA/DEN, EDF R&D
7 // File : PyInterp_Dispatcher.cxx
8 // Author : Sergey ANIKIN, OCC
13 #include <PyInterp_base.h>
14 #include <PyInterp_Dispatcher.h>
15 #include <PyInterp_Watcher.h>
17 #include <qapplication.h>
20 //#include <utilities.h>
23 PyInterp_Dispatcher* PyInterp_Dispatcher::myInstance = 0;
25 void PyInterp_Request::process()
30 //if ( !IsSync() && getListener() && getEvent() )
31 if ( getListener() && getEvent() )
36 void PyInterp_Request::safeExecute()
41 void PyInterp_Request::Destroy( PyInterp_Request* request )
43 // Lock and unlock the mutex to avoid errors on its deletion
44 request->myMutex.lock();
45 request->myMutex.unlock();
49 QEvent* PyInterp_Request::createEvent() const
51 return new PyInterp_Event( PyInterp_Event::NOTIFY, (PyInterp_Request*)this );
54 QEvent* PyInterp_Request::getEvent()
56 //if ( !myEvent && !IsSync() )
58 myEvent = createEvent();
62 void PyInterp_Request::postEvent()
64 #if QT_VERSION >= 0x030303
65 // MESSAGE("*** PyInterp_Request::postEvent(): for Qt 3.3.3")
66 QApplication::postEvent( getListener(), getEvent() );
68 // MESSAGE("*** PyInterp_Request::postEvent(): for Qt 3.0.5")
69 QThread::postEvent( getListener(), getEvent() );
73 void PyInterp_Request::setListener( QObject* o )
80 void PyInterp_LockRequest::safeExecute()
83 PyLockWrapper aLock = getInterp()->GetLockWrapper();
88 PyInterp_Event::~PyInterp_Event()
90 PyInterp_Request::Destroy( myRequest );
94 PyInterp_Dispatcher* PyInterp_Dispatcher::Get()
97 myInstance = new PyInterp_Dispatcher();
101 PyInterp_Dispatcher::PyInterp_Dispatcher()
104 myWatcher = new PyInterp_Watcher();
107 PyInterp_Dispatcher::~PyInterp_Dispatcher()
109 // Clear the request queue
112 for ( std::list<PyInterp_Request*>::iterator it = myQueue.begin(); it != myQueue.end(); ++it )
113 PyInterp_Request::Destroy( *it );
116 myQueueMutex.unlock();
118 // Wait for run() to finish
125 bool PyInterp_Dispatcher::IsBusy() const
130 void PyInterp_Dispatcher::Exec( PyInterp_Request* theRequest )
135 //if ( theRequest->IsSync() && !IsBusy() ) // synchronous processing - nothing is done if dispatcher is busy!
136 if ( theRequest->IsSync() ) // synchronous processing - nothing is done if dispatcher is busy!
137 processRequest( theRequest );
138 else { // asynchronous processing
140 myQueue.push_back( theRequest );
141 if ( theRequest->getListener() )
142 QObject::connect( theRequest->getListener(), SIGNAL( destroyed( QObject* ) ), myWatcher, SLOT( onDestroyed( QObject* ) ) );
143 myQueueMutex.unlock();
150 void PyInterp_Dispatcher::run()
152 // MESSAGE("*** PyInterp_Dispatcher::run(): STARTED")
153 PyInterp_Request* aRequest;
155 // prepare for queue size check
158 while( myQueue.size() ) {
159 // MESSAGE("*** PyInterp_Dispatcher::run(): next request taken from the queue")
160 aRequest = myQueue.front();
162 // let other threads append their requests to the end of the queue
163 myQueueMutex.unlock();
165 // processRequest() may delete a request, so this pointer must not be used
166 // after request is processed!
167 processRequest( aRequest );
169 // prepare for removal of the first request in the queue
171 // IMPORTANT: the first item could have been removed by objectDestroyed() --> we have to check it
172 if ( myQueue.front() == aRequest ) // It's still here --> remove it
175 // MESSAGE("*** PyInterp_Dispatcher::run(): request processed")
178 myQueueMutex.unlock();
179 // MESSAGE("*** PyInterp_Dispatcher::run(): FINISHED")
182 void PyInterp_Dispatcher::processRequest( PyInterp_Request* theRequest )
184 theRequest->process();
187 void PyInterp_Dispatcher::objectDestroyed( const QObject* o )
189 // prepare for modification of the queue
192 for ( std::list<RequestPtr>::iterator it = myQueue.begin(); it != myQueue.end(); ++it ){
193 if ( o == (*it)->getListener() ){
194 (*it)->setListener( 0 ); // to prevent event posting
195 it = myQueue.erase( it );
199 myQueueMutex.unlock();