1// -*- tab-width: 4; -*- 2// 3// The contents of this file are subject to the Mozilla Public 4// License Version 1.1 (the "License"); you may not use this file 5// except in compliance with the License. You may obtain a copy of 6// the License at http://www.mozilla.org/MPL/ 7// 8// Software distributed under the License is distributed on an "AS 9// IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or 10// implied. See the License for the specific language governing 11// rights and limitations under the License. 12// 13// The Original Code is State Machine Compiler (SMC). 14// 15// The Initial Developer of the Original Code is Charles W. Rapp. 16// Portions created by Charles W. Rapp are 17// Copyright (C) 2000 - 2003 Charles W. Rapp. 18// All Rights Reserved. 19// 20// Contributor(s): 21// 22// TaskManager -- 23// 24// The task manager is responsible for executing tasks. This 25// state machine tracks whether the manager has any tasks to run 26// and how long a task is executed. 27// 28// RCS ID 29// $Id: taskManager.sm,v 1.5 2005/05/28 18:02:56 cwrapp Exp $ 30// 31// CHANGE LOG 32// $Log: taskManager.sm,v $ 33// Revision 1.5 2005/05/28 18:02:56 cwrapp 34// Updated Tcl examples, removed EX6. 35// 36// Revision 1.0 2003/12/14 20:35:26 charlesr 37// Initial revision 38// 39 40// Since this task manager does not have any tasks to 41// run, it is in the idle state. 42%start MainMap::Idle 43%class TaskManager 44 45%map MainMap 46%% 47 48// Wait here for some work to do. 49Idle 50Entry 51{ 52 sendMessage(4 "Idle. Looking for a task to run."); 53 checkTaskQueue(); 54} 55{ 56 // Start the highest priority task running and start the slice 57 // timer. 58 RunTask 59 RunningTask 60 { 61 startTask(); 62 } 63 64 // There is now a task a run. 65 TaskCreated 66 RunningTask 67 { 68 startTask(); 69 } 70 71 TaskUnblocked 72 RunningTask 73 { 74 startTask(); 75 } 76 77 Shutdown 78 IdleShutdown 79 { 80 sendMessage(0 "Shutdown started."); 81 setTimer("ShutdownTimeout" 2000); 82 } 83 84 // It is possible for the task to complete before it 85 // receives the suspend request. When this happens, handle 86 // this in the same manner as above. 87 TaskDone 88 [[$ctxt getRunnableTaskCount] > 0] 89 RunningTask 90 { 91 startTask(); 92 } 93 94 TaskDone 95 Idle 96 { 97 stopTimer("ReplyTimeout"); 98 } 99} 100 101// A task has been started and is running. 102RunningTask 103Entry 104{ 105 setTimer("SliceTimeout" 3000); 106} 107Exit 108{ 109 stopTimer("SliceTimeout"); 110} 111{ 112 // The time slice is up. Suspend the task. 113 SliceTimeout 114 SuspendingTask 115 { 116 suspendTask(); 117 } 118 119 // The task has been blocked. Find another task to run. 120 TaskBlocked 121 Idle 122 {} 123 124 // The task has been deleted. Find another task to run. 125 TaskDeleted 126 Idle 127 {} 128 129 // The task has completed its work. Find another task to run. 130 TaskDone 131 Idle 132 {} 133} 134 135// Wait here for the task to suspend. 136SuspendingTask 137Entry 138{ 139 setTimer("ReplyTimeout" 500); 140} 141Exit 142{ 143 stopTimer("ReplyTimeout"); 144} 145{ 146 TaskSuspended 147 Idle 148 {} 149 150 // Wait only so long for the task to reply. 151 ReplyTimeout 152 Idle 153 {} 154 155 // Just in case a task completes exactly at the same time 156 // as the run slice ends. 157 TaskDone 158 Idle 159 {} 160} 161 162// Wait here while the tasks report in. 163ShuttingDown 164{ 165 // A task is reporting it has stopped. When all tasks are 166 // stopped, exit this application. 167 TaskStopped 168 [[$ctxt getRunningTask] == "" && 169 [$ctxt getRunnableTaskCount] == 0 && 170 [$ctxt getBlockedTaskCount] == 0] 171 ShutdownComplete 172 { 173 stopTimer("ShutdownTimeout"); 174 sendMessage(0 "Shutdown completed."); 175 exitApplication(0); 176 } 177 178 // Another task has stopped but there are more. 179 TaskStopped 180 nil 181 {} 182 183 // Timed out waiting for the tasks to die. Clean up and 184 // exit anyway. 185 ShutdownTimeout 186 ShutdownComplete 187 { 188 sendMessage(0 "Timed out waiting for tasks to stop. Forcibly deleting tasks and exiting."); 189 deleteAllTasks(); 190 exitApplication(1); 191 } 192 193 // Since we are shutting down, ignore task suspended 194 // messages. 195 TaskSuspended 196 nil 197 {} 198 199 // If another shutdown is seen, ignore it. 200 Shutdown 201 nil 202 {} 203} 204 205// The system was idle when the shutdown request occurred. 206// Wait for the shutdown timeout, then exit. 207IdleShutdown 208{ 209 ShutdownTimeout 210 ShutdownComplete 211 { 212 sendMessage(0 "Shutdown completed."); 213 exitApplication(0); 214 } 215} 216 217ShutdownComplete 218{ 219 // Once this state is reached, don't do anything. 220 Shutdown 221 nil 222 {} 223 224 Default 225 nil 226 {} 227} 228 229Default 230{ 231 // Tell all tasks to stop. Wait for them to reply but only 232 // so long. If they fail to reply, kill 'em anyway. 233 Shutdown 234 ShuttingDown 235 { 236 sendMessage(0 "Shutdown started. Stopping all tasks."); 237 stopAllTimers(); 238 stopAllTasks(); 239 setTimer("ShutdownTimeout" 5000); 240 } 241 242 // Ignore these events if already running a task. 243 TaskCreated 244 nil 245 {} 246 247 TaskUnblocked 248 nil 249 {} 250 251 // Ignore timeouts when unexpected. 252 SliceTimeout 253 nil 254 {} 255 256 ReplyTimeout 257 nil 258 {} 259} 260 261%% 262