source: trunk/src/nrEngine/Kernel.cpp @ 63

Revision 63, 22.1 KB checked in by art, 11 years ago (diff)
  • small changes in the Kernel and Engine, now Engine do stop the kernel when releasing and let kernel run one tick, so that all tasks can stop before removed
Line 
1/***************************************************************************
2 *                                                                         *
3 *   (c) Art Tevs, MPI Informatik Saarbruecken                             *
4 *       mailto: <tevs@mpi-sb.mpg.de>                                      *
5 *                                                                         *
6 *   This program is free software; you can redistribute it and/or modify  *
7 *   it under the terms of the GNU General Public License as published by  *
8 *   the Free Software Foundation; either version 2 of the License, or     *
9 *   (at your option) any later version.                                   *
10 *                                                                         *
11 ***************************************************************************/
12
13
14#include <nrEngine/Kernel.h>
15#include <nrEngine/Profiler.h>
16#include <nrEngine/events/KernelTaskEvent.h>
17#include <nrEngine/EventManager.h>
18#include <nrEngine/StdHelpers.h>
19#include <nrEngine/Log.h>
20
21namespace nrEngine {
22
23        std::list< SharedPtr<ITask> >::iterator Kernel::_loopIterator;
24
25        //-------------------------------------------------------------------------
26        Kernel::Kernel(){
27                taskList.clear();
28                pausedTaskList.clear();
29                lastTaskID = 0;
30                bTaskStarted = false;
31                bInitializedRoot = false;
32                _bSystemTasksAccessable = false;
33                sendEvents(true);
34        }
35
36        //-------------------------------------------------------------------------
37        Kernel::~Kernel()
38    {
39                StopExecution();
40
41                taskList.clear();
42                pausedTaskList.clear();
43
44                // Log that kernel is down
45                NR_Log(Log::LOG_KERNEL, "Kernel subsystem is down");
46        }
47
48        //-------------------------------------------------------------------------
49        void Kernel::lockSystemTasks()
50        {
51                _bSystemTasksAccessable = true;
52        }
53
54        //-------------------------------------------------------------------------
55        void Kernel::unlockSystemTasks()
56        {
57                _bSystemTasksAccessable = false;
58        }
59
60        //-------------------------------------------------------------------------
61        Result Kernel::OneTick()
62        {
63
64                // Profiling of the engine
65                _nrEngineProfile("Kernel::OneTick");
66
67                // start tasks if their are not started before
68                prepareRootTask();
69
70                // get iterator through our std::list
71                PipelineIterator it;
72
73                // iterate through all tasks and start them
74                for (it = taskList.begin(); it != taskList.end(); it++){
75                        if ((*it)->getTaskState() == TASK_STOPPED)
76                                _taskStart(*it);
77                }
78
79                // resetup to the beginning
80                it = taskList.begin();
81
82                // we go always from teh first element in the list, because it is
83                // the system root task
84                _loopStartCycle();
85                while (_loopGetNextTask(taskList.begin(), it, 0) == OK){
86                        SharedPtr<ITask>& t=(*it);
87
88                        if (t && !t->_taskCanKill){
89
90                                // if the task is running
91                                if (t->getTaskState() == TASK_RUNNING){
92
93                                        // do some profiling
94                                        char name[256];
95                                        sprintf(name, "%s::update", t->getTaskName());
96                                        _nrEngineProfile(name);
97
98                                        t->updateTask();
99
100                                        // check if the task should run only once
101                                        if (t->getTaskProperty() & TASK_RUN_ONCE)
102                                                RemoveTask(t->getTaskID());
103
104                                }
105                        }
106                }
107                _loopEndCycle();
108
109                PipelineIterator thisIt;
110                TaskId tempID;
111
112                //loop again to remove dead tasks
113                for( it = taskList.begin(); it != taskList.end();){
114
115                        SharedPtr<ITask> &t=(*it);
116                        bool killed = false;
117
118                        // kill task if we need this
119                        if(t && t->_taskCanKill){
120
121                                _taskStop(t);
122
123                                // remove the task
124                                tempID = t->getTaskID();
125                                NR_Log(Log::LOG_KERNEL, "Task (id=%d) removed", tempID);
126                                it = taskList.erase(it);
127                                killed = true;
128
129                        // check whenver order of the task was changed by outside
130                        }else if (t->_orderChanged){
131                                ChangeTaskOrder(t->getTaskID(), t->getTaskOrder());
132                        }
133
134                        if (!killed) it++;
135                }
136
137                // Now we yield the running thread, so that our system could still
138                // response
139                IThread::yield();
140
141                // return good result
142                return OK;
143        }
144
145
146        //-------------------------------------------------------------------------
147        void Kernel::prepareRootTask()
148        {
149                if (bInitializedRoot) return;
150                bInitializedRoot = true;
151
152                // get iterator through our std::list
153                PipelineIterator it;
154
155                NR_Log(Log::LOG_KERNEL, "Create a system root task in the kernel");
156
157                // firstly we add a dummy system task, which depends on all others.
158                // This task do nothing, but depends on the rest.
159                // This is needed to get all thing worked
160                mRootTask.reset(new EmptyTask());
161                mRootTask->setTaskName("KernelRoot");
162                mRootTask->setTaskType(TASK_SYSTEM);
163
164                // Add the task as system task to the kernel
165                lockSystemTasks();
166                        AddTask(mRootTask, ORDER_SYS_ROOT);
167                unlockSystemTasks();
168
169        }
170
171        //-------------------------------------------------------------------------
172        /*void Kernel::startTasks(){
173
174                NR_Log(Log::LOG_KERNEL, Log::LL_DEBUG, "Start all kernel tasks");
175
176                // start all tasks, which are not running at now
177                for(it = taskList.begin(); it != taskList.end(); it++){
178                        _taskStart(*it);
179                }
180
181                bTaskStarted = true;
182        }
183        */
184
185        //-------------------------------------------------------------------------
186        Result Kernel::_taskStart(SharedPtr<ITask>& task)
187        {
188
189                // no task given, so return error
190                if (!task)
191                        return KERNEL_NO_TASK_FOUND;
192
193                // check if the task is not a thread
194                if (task->getTaskProperty() & TASK_IS_THREAD){
195
196                        SharedPtr<IThread> thread = boost::dynamic_pointer_cast<IThread, ITask>(task);
197                        thread->threadStart();
198                        task->setTaskState(TASK_RUNNING);
199                        task->onStartTask();
200
201                }else{
202
203                        // check for the task states
204                        if (task->getTaskState() == TASK_STOPPED)
205                        {
206                                task->setTaskState(TASK_RUNNING);
207                                task->onStartTask();
208                        }else if (task->getTaskState() == TASK_PAUSED){
209                                return ResumeTask(task->getTaskID());
210                        }
211
212                }
213
214                // send a message about current task state
215                if (bSendEvents){
216                        SharedPtr<Event> msg(new KernelStartTaskEvent(task->getTaskName(), task->getTaskID()));
217                        Engine::sEventManager()->emitSystem(msg);
218                }
219
220                // OK
221                return OK;
222        }
223
224        //-------------------------------------------------------------------------
225        Result Kernel::_taskStop(SharedPtr<ITask>& task)
226        {
227                try{
228                        // no task given, so return error
229                        if (!task)
230                                return KERNEL_NO_TASK_FOUND;
231
232                        // check if the task is not a thread
233                        if (task->getTaskProperty() & TASK_IS_THREAD){
234
235                                SharedPtr<IThread> thread = boost::dynamic_pointer_cast<IThread, ITask>(task);
236                                NR_Log(Log::LOG_KERNEL, "Stop thread/task \"%s\" (id=%d)", task->getTaskName(), task->getTaskID());
237                                thread->threadStop();
238
239                        }else{
240                                // stop the task
241                                NR_Log(Log::LOG_KERNEL, "Stop task \"%s\" (id=%d)",task->getTaskName(), task->getTaskID());
242                                task->stopTask();
243                        }
244
245                } catch (...){
246                        return UNKNOWN_ERROR;
247                }
248
249                // send a message about current task state
250                if (bSendEvents){
251                        SharedPtr<Event> msg(new KernelStopTaskEvent(task->getTaskName(), task->getTaskID()));
252                        Engine::sEventManager()->emitSystem(msg);
253                }
254
255
256                // OK
257                return OK;
258
259        }
260
261        //-------------------------------------------------------------------------
262        /*Result Kernel::StartTask(taskID id){
263
264                SharedPtr<ITask> task = getTaskByID(id);
265
266                if (!task) {
267                        NR_Log(Log::LOG_KERNEL, Log::LL_DEBUG, "Can not start task with id=%d, because such task does not exists", id);
268                        return KERNEL_NO_TASK_FOUND;
269                }
270
271                // check if the task is not a thread
272                return _taskStart(task);
273        }*/
274
275
276        //-------------------------------------------------------------------------
277        Result Kernel::Execute(){
278                try{
279
280                        // Log that kernel is initialized
281                        NR_Log(Log::LOG_KERNEL, "Kernel subsystem is active, start main loop");
282
283                        // loop while we have tasks in our pipeline
284                        while (taskList.size()){
285                                OneTick();
286                        }
287
288                        NR_Log(Log::LOG_KERNEL, "Stop kernel main loop");
289
290                } catch(...){
291                        return UNKNOWN_ERROR;
292                }
293
294                // ok
295                return OK;
296
297        }
298
299
300        //-------------------------------------------------------------------------
301        TaskId Kernel::AddTask (SharedPtr<ITask> t, TaskOrder order, TaskProperty proper){
302
303                prepareRootTask();
304
305                _nrEngineProfile("Kernel::AddTask");
306
307                try {
308
309                        t->_taskOrder = order;
310
311                        // check whenever such task already exists
312                        std::list< SharedPtr<ITask> >::iterator it;
313                        for (it = taskList.begin(); it != taskList.end(); it++){
314                                if ((*it) == t || (*it)->getTaskID() == t->getTaskID() || strcmp((*it)->getTaskName(),t->getTaskName())==0){
315                                        NR_Log(Log::LOG_KERNEL, "Cannot add task \"%s\" because same task was already added!", t->getTaskName());
316                                        return 0;
317                                }
318                        }
319
320                        for (it = pausedTaskList.begin(); it != pausedTaskList.end(); it++){
321                                if ((*it) == t || (*it)->getTaskID() == t->getTaskID() || strcmp((*it)->getTaskName(),t->getTaskName())==0){
322                                        NR_Log(Log::LOG_KERNEL, "Found same task in paused task std::list !");
323                                        return 0;
324                                }
325                        }
326
327                        // check if the given order number is valid
328                        if (t->getTaskOrder() <= ORDER_SYS_LAST && t->getTaskType() == TASK_USER)
329                        {
330                                NR_Log(Log::LOG_KERNEL, "User task are not allowed to work on system order numbers");
331                                return 0;
332                        }
333
334                        // setup some data
335                        t->setTaskProperty(proper);
336                        t->setTaskState(TASK_STOPPED);
337                        t->setTaskID(++lastTaskID);
338
339                        // some debug info
340                        if (proper & TASK_IS_THREAD)
341                                NR_Log(Log::LOG_KERNEL, "Add Task \"%s\" as thread (id = %d)", t->getTaskName(), t->getTaskID());
342                        else
343                                NR_Log(Log::LOG_KERNEL, "Add Task \"%s\" at order = %s (id = %d)", t->getTaskName(), orderToString(int32(t->getTaskOrder())).c_str(), t->getTaskID());
344
345                        // init task and check its return code
346                        if (t->onAddTask() != OK){
347                                NR_Log(Log::LOG_KERNEL, "Cannot initalize Task because of Task internal error");
348                                return 0;
349                        }
350
351                        // find the place for our task according to its order
352                        for( it=taskList.begin(); it != taskList.end(); it++){
353                                SharedPtr<ITask> &comp = (*it);
354                                if (comp->getTaskOrder() >= t->getTaskOrder()) break;
355                        }
356
357                        // add into the list
358                        taskList.insert (it,t);
359
360                } catch(...){
361                        return UNKNOWN_ERROR;
362                }
363
364                // if this is not a root task, then add dependency
365                // also there is no dependency if this is a thread
366                if (t->_taskOrder != ORDER_SYS_ROOT && !(t->getTaskProperty() & TASK_IS_THREAD))
367                        mRootTask->addTaskDependency(t);
368
369                // return the id
370                return t->getTaskID();
371        }
372
373
374        //-------------------------------------------------------------------------
375        Result Kernel::RemoveTask  (TaskId id){
376
377                if (id == 0) return OK;
378
379                try{
380
381                        NR_Log(Log::LOG_KERNEL, "Remove task with id=%d", id);
382
383                        // find the task
384                        PipelineIterator it;
385
386                        // check whenever iterator is valid
387                        if (!_getTaskByID(id, it, TL_RUNNING | TL_SLEEPING)){
388                                NR_Log(Log::LOG_KERNEL, "No such Task (id=%d) found !!!", id);
389                                return KERNEL_NO_TASK_FOUND;
390                        }
391
392                        // check whenever we are allowed to remove the task
393                        if (!areSystemTasksAccessable() && (*it)->getTaskType() == TASK_SYSTEM)
394                        {
395                                NR_Log(Log::LOG_KERNEL, Log::LL_WARNING, "You do not have rights to remove this task!");
396                                return KERNEL_NO_RIGHTS;
397
398                        }else{
399                                // say task want to remove his self
400                                NR_Log(Log::LOG_KERNEL, "Prepare to die: \"%s\" (id=%d)", (*it)->getTaskName(), (*it)->getTaskID());
401                                (*it)->_taskCanKill = true;
402                        }
403
404                } catch(...){
405                        return UNKNOWN_ERROR;
406                }
407
408                // OK
409                return OK;
410        }
411
412
413        //-------------------------------------------------------------------------
414        Result Kernel::SuspendTask  (TaskId id){
415
416                try{
417
418                        NR_Log(Log::LOG_KERNEL, "Suspend task (id=%d)", id);
419
420                        // find the task
421                        PipelineIterator it;
422
423                        // check whenever iterator is valid
424                        if (!_getTaskByID(id, it)){
425                                NR_Log(Log::LOG_KERNEL, "No task with id=%d found", id);
426                                return KERNEL_NO_TASK_FOUND;
427                        }else{
428                                SharedPtr<ITask> &t = (*it);
429
430                                if (!areSystemTasksAccessable() && (*it)->getTaskType() == TASK_SYSTEM){
431                                        NR_Log(Log::LOG_KERNEL, Log::LL_WARNING, "You do not have rights to suspend this task!");
432                                        return KERNEL_NO_RIGHTS;
433                                }else{
434
435                                        // suspend task
436                                        Result res = t->onSuspendTask();
437                                        if (res == OK){
438                                                t->setTaskState(TASK_PAUSED);
439
440                                                // before removing the task from task std::list move it to paused std::list
441                                                // so we can guarantee that task object will be held in memory
442                                                pausedTaskList.push_back(t);
443                                                taskList.erase(it);
444                                                NR_Log(Log::LOG_KERNEL, "Task id=%d is sleeping now", id);
445
446                                                // send a message about current task state
447                                                if (bSendEvents){
448                                                        SharedPtr<Event> msg(new KernelSuspendTaskEvent(t->getTaskName(), t->getTaskID()));
449                                                        Engine::sEventManager()->emitSystem(msg);
450                                                }
451
452                                        }else{
453                                                NR_Log(Log::LOG_KERNEL, Log::LL_WARNING, "Task id=%d can not suspend! Check this!", id);
454                                                return res;
455                                        }
456                                }
457                        }
458
459                } catch(...){
460                        return UNKNOWN_ERROR;
461                }
462
463                // OK
464                return OK;
465        }
466
467        //-------------------------------------------------------------------------
468        Result Kernel::ResumeTask  (TaskId id){
469
470                try{
471
472                        NR_Log(Log::LOG_KERNEL, "Resume task (id=%d)", id);
473
474                        // find the task
475                        PipelineIterator it;
476
477                        // check whenever iterator is valid
478                        if (!_getTaskByID(id, it, TL_SLEEPING)){
479                                NR_Log(Log::LOG_KERNEL, "No task with id=%d found", id);
480                                return KERNEL_NO_TASK_FOUND;
481                        }
482
483                        SharedPtr<ITask> &t = (*it);
484                        if (!areSystemTasksAccessable() && (*it)->getTaskType() == TASK_SYSTEM){
485                                NR_Log(Log::LOG_KERNEL, Log::LL_WARNING, "You do not have rights to resume this task!");
486                                return KERNEL_NO_RIGHTS;
487                        }else{
488
489                                // resume the task
490                                Result res = t->onResumeTask();
491                                if (res == OK){
492                                        t->setTaskState(TASK_RUNNING);
493
494                                        //keep the order of priorities straight
495                                        for( it = taskList.begin(); it != taskList.end(); it++){
496                                                SharedPtr<ITask> &comp=(*it);
497                                                if(comp->getTaskOrder() >= t->getTaskOrder()) break;
498                                        }
499                                        taskList.insert(it,t);
500
501                                        // erase task from paused std::list. Therefor we have to find it in the std::list
502                                        if (_getTaskByID(id, it, TL_SLEEPING)){
503                                                pausedTaskList.erase(it);
504                                        }
505
506                                        // send a message about current task state
507                                        if (bSendEvents){
508                                                SharedPtr<Event> msg(new KernelResumeTaskEvent(t->getTaskName(), t->getTaskID()));
509                                                Engine::sEventManager()->emitSystem(msg);
510                                        }
511
512                                }else{
513                                        NR_Log(Log::LOG_KERNEL, Log::LL_WARNING, "Task id=%d can not resume, so it stay in sleep mode", id);
514                                        return res;
515                                }
516                        }
517
518                } catch(...){
519                        return UNKNOWN_ERROR;
520                }
521
522                // OK
523                return OK;
524        }
525
526        //-------------------------------------------------------------------------
527        Result Kernel::StopExecution(){
528
529                try{
530
531                        NR_Log(Log::LOG_KERNEL, "Stop the kernel subsystem");
532
533                        // iterate through all tasks and kill them
534                        for(PipelineIterator it = taskList.begin(); it != taskList.end(); it++){
535                                NR_Log(Log::LOG_KERNEL, "Prepare to die: \"%s\" (id=%d)", (*it)->getTaskName(), (*it)->getTaskID());
536                                (*it)->_taskCanKill=true;
537                        }
538
539                        // iterate also through all paused tasks and kill them also
540                        for(PipelineIterator it = pausedTaskList.begin(); it != pausedTaskList.end(); it++){
541                                NR_Log(Log::LOG_KERNEL, "Prepare to die: \"%s\" (id=%d)", (*it)->getTaskName(), (*it)->getTaskID());
542                                (*it)->_taskCanKill=true;
543                        }
544
545                        // Info if we do not have any tasks to kill
546                        if (!taskList.size() && !pausedTaskList.size())
547                                NR_Log(Log::LOG_KERNEL, "There is no more tasks to be killed !");
548
549                } catch(...){
550                        return UNKNOWN_ERROR;
551                }
552
553                // OK
554                return OK;
555
556        }
557
558
559        //-------------------------------------------------------------------------
560        Result Kernel::ChangeTaskOrder(TaskId id, TaskOrder order){
561
562                try{
563
564                        NR_Log(Log::LOG_KERNEL, "Change order of task (id=%d) to %d", id, int32(order));
565
566                        // find the task
567                        PipelineIterator it;
568
569                        // check whenever iterator is valid
570                        if (!_getTaskByID(id, it, TL_RUNNING | TL_SLEEPING)){
571                                NR_Log(Log::LOG_KERNEL, "No task with id=%d found", id);
572                                return KERNEL_NO_TASK_FOUND;
573                        }
574
575                        SharedPtr<ITask> &t = (*it);
576
577                        // check if the given order number is valid
578                        if (order <= ORDER_SYS_LAST && t->getTaskType() == TASK_USER)
579                        {
580                                NR_Log(Log::LOG_KERNEL, "User task are not allowed to work on system order numbers!");
581                                return KERNEL_NO_RIGHTS;
582                        }
583
584                        // check for task access rights
585                        if (!areSystemTasksAccessable() && (*it)->getTaskType() == TASK_SYSTEM){
586                                NR_Log(Log::LOG_KERNEL, Log::LL_WARNING, "You do not have rights to change the order of system task!");
587                                return KERNEL_NO_RIGHTS;
588                        }else{
589
590                                // change order of the task
591                                t->setTaskOrder(order);
592                                t->_orderChanged = false;
593
594                                // sort lists
595                                pausedTaskList.sort();
596                                taskList.sort();
597                        }
598
599                } catch(...){
600                        return UNKNOWN_ERROR;
601                }
602
603                // OK
604                return OK;
605        }
606
607        //-------------------------------------------------------------------------
608        bool Kernel::_getTaskByID(TaskId id, PipelineIterator& jt, int32 useList){
609
610                // get std::list we want to search in
611                std::list< SharedPtr<ITask> > *li = NULL;
612
613                // search in normal list
614                if ((useList & TL_RUNNING) == TL_RUNNING){
615                        li = &taskList;
616
617                        // iterate through elements and search for task with same id
618                        PipelineIterator it;
619                        for ( it = li->begin(); it != li->end(); it++){
620                                if ((*it)->getTaskID() == id){
621                                        jt = it;
622                                        return true;
623                                }
624                        }
625                }
626
627                // search in paused list
628                if ((useList & TL_SLEEPING) == TL_SLEEPING){
629                        li = &pausedTaskList;
630
631                        // iterate through elements and search for task with same id
632                        PipelineIterator it;
633                        for ( it = li->begin(); it != li->end(); it++){
634                                if ((*it)->getTaskID() == id){
635                                        jt = it;
636                                        return true;
637                                }
638                        }
639
640                }
641
642                // not found so return an end iterator
643                return false;
644        }
645
646        //-------------------------------------------------------------------------
647        bool Kernel::_getTaskByName(const std::string& name, PipelineIterator& it, int32 useList)
648        {
649
650                // get std::list we want to search in
651                std::list< SharedPtr<ITask> > *li = NULL;
652
653                // search in normal list
654                if ((useList & TL_RUNNING) == TL_RUNNING){
655                        li = &taskList;
656
657                        // iterate through elements and search for task with same id
658                        PipelineIterator jt;
659                        for ( jt = li->begin(); jt != li->end(); jt++){
660                                if ((*jt)->getTaskName() == name){
661                                        it = jt;
662                                        return true;
663                                }
664                        }
665                }
666
667                // search in paused list
668                if ((useList & TL_SLEEPING) == TL_SLEEPING){
669                        li = &pausedTaskList;
670
671                        // iterate through elements and search for task with same id
672                        PipelineIterator jt;
673                        for ( jt = li->begin(); jt != li->end(); jt++){
674                                if ((*jt)->getTaskName() == name){
675                                        it = jt;
676                                        return true;
677                                }
678                        }
679                }
680
681                // not found so return end iterator
682                return false;
683        }
684
685        //-------------------------------------------------------------------------
686        SharedPtr<ITask> Kernel::getTaskByID(TaskId id){
687                try{
688
689                        // find the task
690                        PipelineIterator it;
691
692                        // check whenever iterator is valid
693                        if (!_getTaskByID(id, it, TL_RUNNING | TL_SLEEPING)){
694                                NR_Log(Log::LOG_KERNEL, "getTaskByID: No task with id=%d found", id);
695                                return SharedPtr<ITask>();
696                        }
697
698                        // check the rights
699                        if (!areSystemTasksAccessable() && (*it)->getTaskType() == TASK_SYSTEM){
700                                NR_Log(Log::LOG_KERNEL, Log::LL_WARNING, "You do not have rights to access to this task!");
701                                return SharedPtr<ITask>();
702                        }
703
704                        return *it;
705
706                } catch(...){
707                        return SharedPtr<ITask>();
708                }
709
710        }
711
712
713        //-------------------------------------------------------------------------
714        SharedPtr<ITask> Kernel::getTaskByName(const std::string& name){
715                try{
716
717                        // find the task
718                        PipelineIterator it;
719
720                        // check whenever iterator is valid
721                        if (!_getTaskByName(name, it, TL_RUNNING | TL_SLEEPING)){
722                                NR_Log(Log::LOG_KERNEL, "getTaskByName: No task with name=%s found", name.c_str());
723                                return SharedPtr<ITask>();
724                        }
725
726                        // check the rights
727                        if (!areSystemTasksAccessable() && (*it)->getTaskType() == TASK_SYSTEM){
728                                NR_Log(Log::LOG_KERNEL, Log::LL_WARNING, "You do not have rights to access to this task!");
729                                return SharedPtr<ITask>();
730                        }
731
732                        return *it;
733
734                } catch(...){
735                        return SharedPtr<ITask>();
736                }
737        }
738
739        //-------------------------------------------------------------------------
740        Result Kernel::_loopStartCycle()
741        {
742
743                // Profiling of the engine
744                _nrEngineProfile("Kernel::_loopStartCycle");
745
746                // iterate through the tasks and mark them as non visited
747                _loopIterator = taskList.begin();
748                while (_loopIterator != taskList.end())
749                {
750                        (*_loopIterator)->_taskGraphColor = 0;
751                        _loopIterator ++;
752                }
753
754                _loopIterator = pausedTaskList.begin();
755                while (_loopIterator != pausedTaskList.end())
756                {
757                        (*_loopIterator)->_taskGraphColor = 0;
758                        _loopIterator ++;
759                }
760
761
762                _loopIterator = taskList.begin();
763
764                return OK;
765        }
766
767        //-------------------------------------------------------------------------
768        Result Kernel::_loopGetNextTask(PipelineIterator it, PipelineIterator& result, int depth)
769        {
770                // Profiling of the engine
771                _nrEngineProfile("Kernel::_loopGetNextTask");
772
773                // check whenever this is the end
774                if (it == taskList.end()) return KERNEL_END_REACHED;
775
776                // get the task in this iterator
777                const SharedPtr<ITask>& t = *it;
778
779                if (t->_taskGraphColor == 1) return KERNEL_CIRCULAR_DEPENDENCY;
780                if (t->_taskGraphColor == 2) return KERNEL_END_REACHED;
781
782                t->_taskGraphColor = 1;
783
784                // now check if the task has got childrens
785                if (t->_taskDependencies.size() > 0)
786                {
787
788                        // do for each child call this function recursively
789                        /*for (uint32 i = 0; i < t->_taskDependencies.size(); i++)
790                        {
791                                PipelineIterator jt;
792                                if (!_getTaskByID(t->_taskDependencies[i], jt, TL_RUNNING | TL_SLEEPING)) return KERNEL_TASK_MISSING;
793
794                                // check whenever the child was already visited
795                                if ((*jt)->_taskGraphColor != 2){
796                                        Result ret = _loopGetNextTask(jt, result, depth+1);
797
798                                        // we return OK only if we have not found any circularity
799                                        // and we are on the top (root-node)
800                                        if (ret != OK){
801                                                t->_taskGraphColor = 0;
802                                                if (depth == 0 && ret != KERNEL_CIRCULAR_DEPENDENCY) return OK;
803                                                return ret;
804                                        }
805                                }
806                        }*/
807
808                        // iterate through all dependencies and check them
809                        std::list<SharedPtr<ITask> >::iterator jt = t->_taskDependencies.begin();
810                        for (; jt != t->_taskDependencies.end(); jt ++)
811                        {
812                                // check whenever the child was already visited
813                                if ((*jt)->_taskGraphColor != 2){
814                                        Result ret = _loopGetNextTask(jt, result, depth+1);
815
816                                        // we return OK only if we have not found any circularity
817                                        // and we are on the top (root-node)
818                                        if (ret != OK){
819                                                t->_taskGraphColor = 0;
820                                                if (depth == 0 && ret != KERNEL_CIRCULAR_DEPENDENCY) return OK;
821                                                return ret;
822                                        }
823                                }
824
825                        }
826
827                // we do not have childs, so this is a leaf node
828                }
829
830                // all our chlds are visited, so return the node itself
831                t->_taskGraphColor = 2;
832                result = it;
833                return KERNEL_LEAF_TASK;
834
835        }
836
837        //-------------------------------------------------------------------------
838        Result Kernel::_loopEndCycle()
839        {
840                return OK;
841        }
842
843}; //namespace nrEngine
844
Note: See TracBrowser for help on using the repository browser.