2 #include "PyInterp_Dispatcher.h" // !!! WARNING !!! THIS INCLUDE MUST BE THE VERY FIRST !!!
3 #include "PyInterp_Interp.h"
4 #include "PyInterp_Watcher.h"
5 #include "PyInterp_Request.h"
8 #include <QCoreApplication>
10 PyInterp_Dispatcher* PyInterp_Dispatcher::myInstance = 0;
12 void PyInterp_Request::process()
16 bool isSync = IsSync();
22 processEvent( listener() );
28 void PyInterp_Request::safeExecute()
30 //ProcessVoidEvent( new PyInterp_ExecuteEvent( this ) );
34 void PyInterp_Request::Destroy( PyInterp_Request* request )
36 // Lock and unlock the mutex to avoid errors on its deletion
37 request->myMutex.lock();
38 request->myMutex.unlock();
42 QEvent* PyInterp_Request::createEvent()
44 return new PyInterp_Event( PyInterp_Event::ES_NOTIFY, this );
47 void PyInterp_Request::processEvent( QObject* o )
52 QEvent* e = createEvent();
57 QCoreApplication::postEvent( o, e );
60 QCoreApplication::sendEvent( o, e );
65 void PyInterp_Request::setListener( QObject* o )
72 void PyInterp_LockRequest::safeExecute()
75 PyLockWrapper aLock = getInterp()->GetLockWrapper();
76 //ProcessVoidEvent( new PyInterp_ExecuteEvent( this ) );
81 PyInterp_Event::~PyInterp_Event()
83 PyInterp_Request::Destroy( myRequest );
87 PyInterp_Dispatcher* PyInterp_Dispatcher::Get()
90 myInstance = new PyInterp_Dispatcher();
94 PyInterp_Dispatcher::PyInterp_Dispatcher()
97 myWatcher = new PyInterp_Watcher();
100 PyInterp_Dispatcher::~PyInterp_Dispatcher()
102 // Clear the request queue
105 QListIterator<RequestPtr> it( myQueue );
106 while ( it.hasNext() )
107 PyInterp_Request::Destroy( it.next() );
110 myQueueMutex.unlock();
112 // Wait for run() to finish
119 bool PyInterp_Dispatcher::IsBusy() const
124 void PyInterp_Dispatcher::Exec( PyInterp_Request* theRequest )
129 //if ( theRequest->IsSync() && !IsBusy() ) // synchronous processing - nothing is done if dispatcher is busy!
130 if ( theRequest->IsSync() ) // synchronous processing
131 processRequest( theRequest );
132 else // asynchronous processing
135 myQueue.enqueue( theRequest );
136 if ( theRequest->listener() )
137 QObject::connect( theRequest->listener(), SIGNAL( destroyed( QObject* ) ), myWatcher, SLOT( onDestroyed( QObject* ) ) );
138 myQueueMutex.unlock();
145 void PyInterp_Dispatcher::run()
147 // MESSAGE("*** PyInterp_Dispatcher::run(): STARTED")
148 PyInterp_Request* aRequest;
150 // prepare for queue size check
153 while( myQueue.size() ) {
154 // MESSAGE("*** PyInterp_Dispatcher::run(): next request taken from the queue")
155 aRequest = myQueue.head();
157 // let other threads append their requests to the end of the queue
158 myQueueMutex.unlock();
160 // processRequest() may delete a request, so this pointer must not be used
161 // after request is processed!
162 processRequest( aRequest );
164 // prepare for removal of the first request in the queue
166 // IMPORTANT: the first item could have been removed by objectDestroyed() --> we have to check it
167 if ( myQueue.head() == aRequest ) // It's still here --> remove it
170 // MESSAGE("*** PyInterp_Dispatcher::run(): request processed")
173 myQueueMutex.unlock();
174 // MESSAGE("*** PyInterp_Dispatcher::run(): FINISHED")
177 void PyInterp_Dispatcher::processRequest( PyInterp_Request* theRequest )
179 theRequest->process();
182 void PyInterp_Dispatcher::objectDestroyed( const QObject* o )
184 // prepare for modification of the queue
187 QMutableListIterator<RequestPtr> it( myQueue );
188 while ( it.hasNext() )
190 RequestPtr r = it.next();
191 if ( o == r->listener() )
193 r->setListener( 0 ); // to prevent event posting
198 myQueueMutex.unlock();