34 #include <QMutexLocker> 39 ArnScriptWatchdogThread* watchdogThread)
41 _jobConfig = jobConfig;
42 _jobFactory = jobFactory;
43 _watchdogThread = watchdogThread;
47 ArnScriptJobThread::~ArnScriptJobThread()
55 void ArnScriptJobThread::run()
58 ArnScriptJobSingle jobPreem( _jobConfig, _jobFactory, _watchdogThread);
68 ArnScriptWatchdogThread* watchdogThread)
70 _jobConfig = jobConfig;
71 _jobFactory = jobFactory;
72 _watchdogThread = watchdogThread;
73 _scriptChanged =
false;
79 connect( _jobConfig, SIGNAL(scriptChanged(
int)),
this, SLOT(doScriptChanged(
int)), Qt::QueuedConnection);
83 ArnScriptJobSingle::~ArnScriptJobSingle()
88 void ArnScriptJobSingle::newScriptJob()
93 _watchdogThread->removeWatchdog( _job->watchdog());
98 connect( _job, SIGNAL(errorText(QString)), _jobConfig, SIGNAL(errorText(QString)));
100 _jobConfig->doSetupJob( _job, _jobFactory);
101 connect( _job, SIGNAL(scheduleRequest(
int)),
102 this, SLOT(doScheduleRequest(
int)), Qt::QueuedConnection);
103 connect( _job, SIGNAL(quitRequest(
int)),
104 this, SLOT(doQuitRequest(
int)));
106 _watchdogThread->addWatchdog( _job->watchdog());
110 void ArnScriptJobSingle::doScheduleRequest(
int callerId)
112 if ((_runningId != 0) && (callerId != 0) && (_runningId != callerId))
return;
115 if (_runningId != 0) {
121 if (_job->isRunable()) {
122 _runningId = _job->id();
128 void ArnScriptJobSingle::doQuitRequest(
int callerId)
132 if (_scriptChanged) {
133 _scriptChanged =
false;
136 doScheduleRequest(0);
141 void ArnScriptJobSingle::doScriptChanged(
int id)
145 _scriptChanged =
true;
147 QMetaObject::invokeMethod( _job,
149 Qt::DirectConnection);
156 #ifdef ARNUSE_SCRIPTJS 157 ArnScriptWatchdogRun::ArnScriptWatchdogRun( ArnScriptWatchdogThread& watchdogThread)
159 _watchdogThread = &watchdogThread;
163 ArnScriptWatchdogRun::~ArnScriptWatchdogRun()
168 void ArnScriptWatchdogRun::addWatchdog( ArnScriptWatchdog* watchdog)
170 watchdog->setParent(
this);
175 void ArnScriptWatchdogRun::removeWatchdog( ArnScriptWatchdog* watchdog)
181 ArnScriptWatchdogThread::ArnScriptWatchdogThread( QObject* parent)
187 ArnScriptWatchdogThread::~ArnScriptWatchdogThread()
194 void ArnScriptWatchdogThread::addWatchdog( ArnScriptWatchdog* watchdog)
196 if (!watchdog)
return;
198 QMutexLocker mutexLocker( &_mutex);
200 if (_wdTab.contains( watchdog))
return;
203 if (!_isReady)
return;
205 mutexLocker.unlock();
207 addWatchdogNow( watchdog);
212 void ArnScriptWatchdogThread::addWatchdogNow( ArnScriptWatchdog* watchdog)
214 watchdog->setParent( arnNullptr);
215 watchdog->moveToThread( _watchdogRun->thread());
217 QMetaObject::invokeMethod( _watchdogRun, [watchdog,
this]() {
218 _watchdogRun->addWatchdog( watchdog);
219 }, Qt::QueuedConnection);
224 void ArnScriptWatchdogThread::removeWatchdog( ArnScriptWatchdog* watchdog)
226 if (!watchdog)
return;
228 QMutexLocker mutexLocker( &_mutex);
230 if (!_wdTab.contains( watchdog))
return;
231 _wdTab.removeAll( watchdog);
233 if (!_isReady)
return;
235 mutexLocker.unlock();
237 watchdog->setJsEngine( arnNullptr);
238 QMetaObject::invokeMethod( _watchdogRun, [watchdog,
this]() {
239 _watchdogRun->removeWatchdog( watchdog);
240 }, Qt::QueuedConnection);
244 void ArnScriptWatchdogThread::run()
247 _watchdogRun =
new ArnScriptWatchdogRun( *
this);
249 QTimer::singleShot( 0, _watchdogRun, [
this]() {
250 QMetaObject::invokeMethod(
this, [
this]() {
252 }, Qt::QueuedConnection);
257 _watchdogRun = arnNullptr;
261 void ArnScriptWatchdogThread::postInit()
265 foreach( ArnScriptWatchdog* watchdog, _wdTab) {
266 addWatchdogNow( watchdog);
277 ArnScriptWatchdogThread::ArnScriptWatchdogThread( QObject* parent)
280 QTimer::singleShot( 0,
this, SIGNAL(ready()));
284 void ArnScriptWatchdogThread::start()
289 void ArnScriptWatchdogThread::addWatchdog( ArnScriptWatchdog* watchdog)
291 if (!watchdog)
return;
297 void ArnScriptWatchdogThread::removeWatchdog( ArnScriptWatchdog* watchdog)
313 _jobFactory = arnNullptr;
314 _watchdogThread = arnNullptr;
320 if (!jobConfig)
return;
323 jobSlot.startPrio = prio;
324 jobSlot.jobConfig = jobConfig;
325 _idToSlot.insert( jobConfig->
id(), _jobSlots.size());
326 _jobSlots += jobSlot;
332 _jobFactory = jobFactory;
338 _watchdogThread =
new ArnScriptWatchdogThread(
this);
339 _watchdogThread->start();
343 doCooperativeStart();
353 void ArnScriptJobs::doCooperativeStart()
356 for (
int i = 0; i < _jobSlots.size(); ++i) {
357 JobSlot& jobSlot = _jobSlots[i];
358 newScriptJob( jobSlot);
360 connect( jobSlot.jobConfig, SIGNAL(scriptChanged(
int)),
this, SLOT(setScriptChanged(
int)));
362 doScheduleRequest(0);
366 void ArnScriptJobs::doPreemtiveStart()
368 connect( _watchdogThread, SIGNAL(ready()),
this, SLOT(doPreemtiveStartNow()));
373 void ArnScriptJobs::doPreemtiveStartNow()
375 for (
int i = 0; i < _jobSlots.size(); ++i) {
376 JobSlot& jobSlot = _jobSlots[i];
377 jobSlot.thread =
new ArnScriptJobThread( jobSlot.jobConfig, _jobFactory, _watchdogThread);
378 jobSlot.thread->start();
384 void ArnScriptJobs::doScheduleRequest(
int callerId)
387 if ((_runningId != 0) && (callerId != 0) && (_runningId != callerId))
return;
390 if (_runningId != 0) {
392 JobSlot& jobSlot = _jobSlots[ _runningIndex];
393 jobSlot.job->leaveScript();
395 for (
int i = 0; i < _jobSlots.size(); ++i) {
396 if (_jobSlots.at(i).curPrio > -100)
397 _jobSlots[i].curPrio -= 100 / _jobSlots[i].startPrio;
400 jobSlot.curPrio = 10000;
407 for (
int i = 0; i < _jobSlots.size(); ++i) {
408 JobSlot& jobSlot = _jobSlots[i];
409 if (jobSlot.scriptChanged) {
410 QMetaObject::invokeMethod( jobSlot.job,
412 Qt::DirectConnection);
413 jobSlot.scriptChanged =
false;
414 newScriptJob( jobSlot);
420 int hiPrioIndex = -1;
421 for (
int i = 0; i < _jobSlots.size(); ++i) {
422 JobSlot& jobSlot = _jobSlots[i];
423 if ((jobSlot.job->isRunable()) && (jobSlot.curPrio < hiPrio)) {
424 hiPrio = jobSlot.curPrio;
428 if (hiPrioIndex >= 0) {
429 _runningIndex = hiPrioIndex;
430 JobSlot& jobSlot = _jobSlots[ _runningIndex];
431 _runningId = jobSlot.job->id();
434 jobSlot.job->enterScript();
440 void ArnScriptJobs::newScriptJob( JobSlot& jobSlot)
443 _watchdogThread->removeWatchdog( jobSlot.job->watchdog());
446 jobSlot.job =
new ArnScriptJob( jobSlot.jobConfig->id(),
this);
447 connect( jobSlot.job, SIGNAL(errorText(QString)), jobSlot.jobConfig, SIGNAL(errorText(QString)));
449 jobSlot.jobConfig->doSetupJob( jobSlot.job, _jobFactory);
450 connect( jobSlot.job, SIGNAL(scheduleRequest(
int)),
451 this, SLOT(doScheduleRequest(
int)), Qt::QueuedConnection);
453 _watchdogThread->addWatchdog( jobSlot.job->watchdog());
458 void ArnScriptJobs::setScriptChanged(
int id)
460 int i = _idToSlot.value(
id, -1);
463 _jobSlots[i].scriptChanged =
true;
465 if (_runningId == 0) {
466 doScheduleRequest( 0);
ArnScriptJobs(QObject *parent=arnNullptr)
void setFactory(ArnScriptJobFactory *jobFactory)
Must be thread-safe as subclassed.
Is thread-safe (except doSetupJob)
Interface class to be normally used, is also Script Job interface.
void setWatchDogTime(int time)
void addJob(ArnScriptJobControl *jobConfig, int prio=1)
void start(Type type=Type::Cooperative)