1 // Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D
3 // This library is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU Lesser General Public
5 // License as published by the Free Software Foundation; either
6 // version 2.1 of the License.
8 // This library is distributed in the hope that it will be useful
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 // Lesser General Public License for more details.
13 // You should have received a copy of the GNU Lesser General Public
14 // License along with this library; if not, write to the Free Software
15 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
19 // SALOME SALOMEGUI : implementation of desktop and GUI kernel
21 // File : PyInterp_Dispatcher.cxx
22 // Author : Sergey ANIKIN, OCC
27 #include <PyInterp_base.h>
28 #include <PyInterp_Dispatcher.h>
29 #include <PyInterp_Watcher.h>
31 #include <qapplication.h>
34 //#include <utilities.h>
37 PyInterp_Dispatcher* PyInterp_Dispatcher::myInstance = 0;
39 void PyInterp_Request::process()
44 //if ( !IsSync() && getListener() && getEvent() )
45 if ( getListener() && getEvent() )
50 void PyInterp_Request::safeExecute()
55 void PyInterp_Request::Destroy( PyInterp_Request* request )
57 // Lock and unlock the mutex to avoid errors on its deletion
58 request->myMutex.lock();
59 request->myMutex.unlock();
63 QEvent* PyInterp_Request::createEvent() const
65 return new PyInterp_Event( PyInterp_Event::NOTIFY, (PyInterp_Request*)this );
68 QEvent* PyInterp_Request::getEvent()
70 //if ( !myEvent && !IsSync() )
72 myEvent = createEvent();
76 void PyInterp_Request::postEvent()
78 #if QT_VERSION >= 0x030303
79 // MESSAGE("*** PyInterp_Request::postEvent(): for Qt 3.3.3")
80 QApplication::postEvent( getListener(), getEvent() );
82 // MESSAGE("*** PyInterp_Request::postEvent(): for Qt 3.0.5")
83 QThread::postEvent( getListener(), getEvent() );
87 void PyInterp_Request::setListener( QObject* o )
94 void PyInterp_LockRequest::safeExecute()
97 PyLockWrapper aLock = getInterp()->GetLockWrapper();
102 PyInterp_Event::~PyInterp_Event()
104 PyInterp_Request::Destroy( myRequest );
108 PyInterp_Dispatcher* PyInterp_Dispatcher::Get()
111 myInstance = new PyInterp_Dispatcher();
115 PyInterp_Dispatcher::PyInterp_Dispatcher()
118 myWatcher = new PyInterp_Watcher();
121 PyInterp_Dispatcher::~PyInterp_Dispatcher()
123 // Clear the request queue
126 for ( std::list<PyInterp_Request*>::iterator it = myQueue.begin(); it != myQueue.end(); ++it )
127 PyInterp_Request::Destroy( *it );
130 myQueueMutex.unlock();
132 // Wait for run() to finish
139 bool PyInterp_Dispatcher::IsBusy() const
144 void PyInterp_Dispatcher::Exec( PyInterp_Request* theRequest )
149 //if ( theRequest->IsSync() && !IsBusy() ) // synchronous processing - nothing is done if dispatcher is busy!
150 if ( theRequest->IsSync() ) // synchronous processing - nothing is done if dispatcher is busy!
151 processRequest( theRequest );
152 else { // asynchronous processing
154 myQueue.push_back( theRequest );
155 if ( theRequest->getListener() )
156 QObject::connect( theRequest->getListener(), SIGNAL( destroyed( QObject* ) ), myWatcher, SLOT( onDestroyed( QObject* ) ) );
157 myQueueMutex.unlock();
164 void PyInterp_Dispatcher::run()
166 // MESSAGE("*** PyInterp_Dispatcher::run(): STARTED")
167 PyInterp_Request* aRequest;
169 // prepare for queue size check
172 while( myQueue.size() ) {
173 // MESSAGE("*** PyInterp_Dispatcher::run(): next request taken from the queue")
174 aRequest = myQueue.front();
176 // let other threads append their requests to the end of the queue
177 myQueueMutex.unlock();
179 // processRequest() may delete a request, so this pointer must not be used
180 // after request is processed!
181 processRequest( aRequest );
183 // prepare for removal of the first request in the queue
185 // IMPORTANT: the first item could have been removed by objectDestroyed() --> we have to check it
186 if ( myQueue.front() == aRequest ) // It's still here --> remove it
189 // MESSAGE("*** PyInterp_Dispatcher::run(): request processed")
192 myQueueMutex.unlock();
193 // MESSAGE("*** PyInterp_Dispatcher::run(): FINISHED")
196 void PyInterp_Dispatcher::processRequest( PyInterp_Request* theRequest )
198 theRequest->process();
201 void PyInterp_Dispatcher::objectDestroyed( const QObject* o )
203 // prepare for modification of the queue
206 for ( std::list<RequestPtr>::iterator it = myQueue.begin(); it != myQueue.end(); ++it ){
207 if ( o == (*it)->getListener() ){
208 (*it)->setListener( 0 ); // to prevent event posting
209 it = myQueue.erase( it );
213 myQueueMutex.unlock();