📄 taskmanager.tcl
字号:
# # The contents of this file are subject to the Mozilla Public# License Version 1.1 (the "License"); you may not use this file# except in compliance with the License. You may obtain a copy of# the License at http://www.mozilla.org/MPL/# # Software distributed under the License is distributed on an "AS# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or# implied. See the License for the specific language governing# rights and limitations under the License.# # The Original Code is State Machine Compiler (SMC).# # The Initial Developer of the Original Code is Charles W. Rapp.# Portions created by Charles W. Rapp are# Copyright (C) 2000 - 2003 Charles W. Rapp.# All Rights Reserved.# # Contributor(s):## TaskManager --## Responsible for creating, executing and destroying tasks.# Maintains a sorted list of tasks and runs the highest# priority task for a specified time slice.## RCS ID# $Id: taskManager.tcl,v 1.4 2005/05/28 18:02:56 cwrapp Exp $## CHANGE LOG# $Log: taskManager.tcl,v $# Revision 1.4 2005/05/28 18:02:56 cwrapp# Updated Tcl examples, removed EX6.## Revision 1.0 2003/12/14 20:36:00 charlesr# Initial revision#package require statemap;source ./taskManager_sm.tcl;class TaskManager {# Member data. private variable _fsm; # The queue of runnable tasks sorted by priority. private variable _runnableTaskQueue; # Tasks that are blocked and so can't run. private variable _blockedTaskList; # These tasks are dead and are waiting to be deleted. private variable _zombieTaskList; # This is the task that is currently executing. private variable _runningTask; # When a timer is created, it's name and associated # Tcl timer ID are stored in this array. private variable _timerTable; # Put the garbage collection timer its own variable. private variable _garbageTimerID; # Store the application exit code here. private variable _exitCode;# Member functions. constructor {} { set _runnableTaskQueue {}; set _blockedTaskList {}; set _zombieTaskList {}; set _runningTask ""; set _garbageTimerID -1; set _exitCode 0; set _fsm [TaskManagerContext #auto $this]; # Uncomment to see debug output. # _fsm setDebugFlag 1; } destructor { # Delete all open timers. foreach Timer [array names _timerTable] { if {$_timerTable($Timer) >= 0} { after cancel $_timerTable($Timer); set _timerTable($Timer) -1; } } if {$_garbageTimerID >= 0} { after cancel $_garbageTimerID; set _garbageTimerID -1; } # Delete all zombie tasks. foreach Task $_zombieTaskList { delete object $Task; } } # timeout -- # # A timer has expired. Remove the timer from the # timer table and issue the specified transition. # This method should only be used as a callback to # after. # # Arguments: # transition The task manager transition. # # Results: # None. public method timeout {transition} { $_fsm $transition; return -code ok; } # collectGarbage -- # # Delete all zombie tasks. # # Arguments: # None. # # Results: # None. public method collectGarbage {} { # Now that the garbage collection timer has expired, # reset the timer ID. set _garbageTimerID -1; foreach Task $_zombieTaskList { delete object $Task; } set _zombieTaskList {}; return -code ok; } # These methods are called by the GUI controller. # createTask -- # # Create a new task with the specified parameters. # # Arguments: # name Task name. # priority Task fixed priority. # time How long the task will run (in seconds). # # Results: # None. public method createTask {name priority time} { # Does a task with this name already exist? if {[string length $name] == 0} { sendMessage 0 "Cannot create task without a name."; } elseif {[string length [FindTask $name]] > 0} { sendMessage 0 "Cannot create task named \"$name\" - a task with that name already exists."; } else { set TaskObj [Task #auto $name $priority $time]; set TaskObj "::TaskManager::$TaskObj"; lappend _runnableTaskQueue $TaskObj; sendMessage 1 "Created task $name (priority: $priority, time: $time)"; $_fsm TaskCreated; } return -code ok; } # suspendTask -- # # Suspend the runnng task. # # Arguments: # None. # # Results: # None. public method suspendTask {} { # Is there a task with this name? if {[string length $_runningTask] != 0} { sendMessage 2 "Suspending task [$_runningTask getName]."; guiController postMessage \ $_runningTask suspend; # Put the task back on to the runnable queue. lappend _runnableTaskQueue $_runningTask; set _runningTask ""; } return -code ok; } # blockTask -- # # Block the specified task. If that task is running, # then remove it. # # Arguments: # taskName A task object's name. # # Results: # None. public method blockTask {taskName} { set Task [FindTask $taskName]; # Is there a task with this name? if {[string length $Task] != 0} { sendMessage 2 "Task $taskName is blocked."; guiController postMessage \ $Task block; if {[string compare $Task $_runningTask] == 0} { # Put the task on to the blocked list. lappend _blockedTaskList $_runningTask; set _runningTask ""; } elseif {[set TaskIndex [lsearch -exact $_runnableTaskQueue $Task]] >= 0} { # Move the task from the runnable queue to the # blocked queue. set _runnableTaskQueue \ [lreplace $_runnableTaskQueue \ $TaskIndex \ $TaskIndex]; lappend _blockedTaskList $Task; } } return -code ok; } # unblockTask -- # # Move a task from the blocked list to the runnable queue. # # Arguments: # taskName A task object's name. # # Results: # None. public method unblockTask {taskName} { set Task [FindTask $taskName]; # Is there a task with this name? if {[string length $Task] != 0} { # Is this task on the blocked list? if {[set TaskIndex [lsearch -exact $_blockedTaskList $Task]] >= 0} { sendMessage 2 "Task $taskName is unblocked."; guiController postMessage \ $Task unblock; # Move the task from the blocked queue to the # runnable queue. set _blockedTaskList \ [lreplace $_blockedTaskList \ $TaskIndex \ $TaskIndex]; lappend _runnableTaskQueue $Task; $_fsm TaskUnblocked; } } return -code ok; } # deleteTask -- # # Delete a task. # # Arguments: # taskName A task object's name. # # Results: # None. public method deleteTask {taskName} { set Task [FindTask $taskName]; # Is there a task with this name? if {[string length $Task] != 0} { # Have the task go and die. guiController postMessage $Task delete; } return -code ok; } # shutdown -- # # Shutdown this application. # # Arguments: # None. # # Results: # None. public method shutdown {} { $_fsm Shutdown; return -code ok; } # The following methods are used by task objects # to communicate with the task manager. # taskDone -- # # The running task has completed its work. # # Arguments: # taskName A task object's name. # # Results: # None. public method taskDone {taskName} { set Task [FindTask $taskName]; if {[string length $Task] > 0} { sendMessage 1 "Task $taskName has completed."; # Is this the running task? if {[string compare $Task $_runningTask] == 0} { set _runningTask ""; $_fsm TaskDone; } elseif {[set TaskIndex [lsearch -exact $_runnableTaskQueue $Task]] >= 0} { # I don't know how a suspended task managed to # complete. Remove it from the runnable list. set _runnableTaskQueue \ [lreplace $_runnableTaskQueue \ $TaskIndex \ $TaskIndex]; } elseif {[set TaskIndex [lsearch -exact $_blockedTaskList $task]] >= 0} { # I don't know how a blocked task managed to # complete. Remove it from the blocked list. set _blockedTaskList \ [lreplace $_blockedTaskList \ $TaskIndex \ $TaskIndex]; } ZombifyTask $Task; } return -code ok; } # taskStopped -- # # A task has stopped and is ready for shutdown. # # Arguments: # taskName A task object's name. # # Results: # None. public method taskStopped {taskName} { set Task [FindTask $taskName]; # Move the state from the blocked list to the zombie. if {[set TaskIndex [lsearch -exact $_blockedTaskList $Task]] >= 0} { sendMessage 1 "Task $taskName is stopped."; set _blockedTaskList \ [lreplace $_blockedTaskList \ $TaskIndex \ $TaskIndex]; ZombifyTask $Task; $_fsm TaskStopped; } else { sendMessage 4 "TaskManager::taskStopped: $taskName not on blocked list."; } return -code ok; } # taskDeleted -- # # A task has stopped and is ready for deletion. # # Arguments: # taskName A task object's name. # # Results: # None. public method taskDeleted {taskName} { set Task [FindTask $taskName]; # Is there a task with this name? if {[string length $Task] != 0} { sendMessage 1 "Task $taskName deleted."; if {[string compare $_runningTask $Task] == 0} { set _runningTask ""; $_fsm TaskDeleted; } elseif {[set TaskIndex [lsearch -exact $_runnableTaskQueue $Task]] >= 0} { # Move the task from the runnable queue to the # blocked queue. set _runnableTaskQueue \ [lreplace $_runnableTaskQueue \
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -