source: nrEngine/src/Kernel.cpp @ 1

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