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