sipxportlib  Version 3.3
OsTask.h
Go to the documentation of this file.
1 //
2 // Copyright (C) 2006-2013 SIPez LLC. All rights reserved.
3 //
4 // Copyright (C) 2004-2006 SIPfoundry Inc.
5 // Licensed by SIPfoundry under the LGPL license.
6 //
7 // Copyright (C) 2004-2006 Pingtel Corp. All rights reserved.
8 // Licensed to SIPfoundry under a Contributor Agreement.
9 //
10 // $$
12 
13 #ifndef _OsTask_h_
14 #define _OsTask_h_
15 
16 // SYSTEM INCLUDES
17 
18 // APPLICATION INCLUDES
19 #include <os/OsDefs.h>
20 #include <os/OsMsgQ.h>
21 #include <os/OsMutex.h>
22 #include <os/OsStatus.h>
23 #include <os/OsSysLog.h>
24 #include <os/OsAtomics.h>
25 #include <os/OsTaskId.h>
26 
27 // DEFINES
28 #define OSTASK_STACK_SIZE_1M 1024*1024
29 // MACROS
30 // EXTERNAL FUNCTIONS
31 // EXTERNAL VARIABLES
32 // CONSTANTS
33 // STRUCTS
34 // TYPEDEFS
35 // FORWARD DECLARATIONS
36 class OsTime;
37 
38 //:Task abstraction
39 // A task represents a thread of execution. All tasks run within the same
40 // address space but have their own stack and program counter. Tasks may be
41 // created and deleted dynamically.
42 //
43 // <p>Users create tasks by:
44 // <ol><li>Deriving a new class based on OsTask or one of its descendants,
45 // and overriding the run() method in the derived class.</li>
46 // <li>Calling the constructor for the derived class.</li>
47 // <li>Invoking the start() method for the derived class. This creates
48 // the corresponding low-level OS task and associates it with the class.</li>
49 // </ol>
50 // <p>Note: Many of the methods in this class are only applicable once the
51 // start() method for the object has been called and the corresponding
52 // low-level task has been created. Accordingly, before a successful call
53 // to start(), most of the methods in this class return the
54 // OS_TASK_NOT_STARTED status.
55 //
56 // <p>Note: carefully read documentation for ackShutdown() and waitUntilShutDown()
57 // methods, or you may get deadlocks.
58 
60 {
61 /* //////////////////////////// PUBLIC //////////////////////////////////// */
62 public:
63 
64  static const int DEF_OPTIONS; // default task execution options
65  static const int DEF_PRIO; // default task priority
66  static const int DEF_STACKSIZE; // default task stack size
67  static const UtlString TASK_PREFIX; // prefix for OsTask names stored in
68  // the name database
69  static const UtlString TASKID_PREFIX; // prefix for taskID stored in the
70  // name database.
71 
73 
74  enum TaskState
75  {
76  UNINITIALIZED, // no low-level task, no name DB entries
77  STARTED, // low-level task and name DB entries exist
78  SHUTTING_DOWN, // requested low-level task shutdown
79  SHUT_DOWN // no low-level task, name DB entries still exist
80  };
81 
86 
87 /* ============================ CREATORS ================================== */
88 
89  virtual OsStatus deleteForce(void) = 0;
90  //:Delete the task even if the task is protected from deletion
91  // After calling this method, the user will still need to delete the
92  // corresponding OsTask object to reclaim its storage.
93 
94 /* ============================ MANIPULATORS ============================== */
95 
96  virtual void requestShutdown(void);
97  //:Request a task shutdown
98  // The run() method of the derived class is expected to call the
99  // isShuttingDown() method to detect when a task shutdown has been
100  // requested. After a task has been shut down, it may be restarted
101  // by calling the start() method.
102 
103  virtual UtlBoolean restart(void) = 0;
104  //:Restart the task
105  // The task is first terminated, and then reinitialized with the same
106  // name, priority, options, stack size, original entry point, and
107  // parameters it had when it was terminated.
108  // Return TRUE if the restart of the task is successful.
109 
110  virtual OsStatus resume(void) = 0;
111  //:Resume the task
112  // This routine resumes the task. The task suspension is cleared, and
113  // the task operates in the remaining state.
114 
115  virtual UtlBoolean start(void) = 0;
116  //:Spawn a new task and invoke its run() method.
117  // Return TRUE if the spawning of the new task is successful.
118  // Return FALSE if the task spawn fails or if the task has already
119  // been started.
120 
121  virtual OsStatus suspend(void) = 0;
122  //:Suspend the task
123  // This routine suspends the task. Suspension is additive: thus, tasks
124  // can be delayed and suspended, or pended and suspended. Suspended,
125  // delayed tasks whose delays expire remain suspended. Likewise,
126  // suspended, pended tasks that unblock remain suspended only.
127 
128  virtual OsStatus setErrno(int errno) = 0;
129  //:Set the errno status for the task
130 
131  virtual OsStatus setOptions(int options) = 0;
132  //:Set the execution options for the task
133  // The only option that can be changed after a task has been created
134  // is whether to allow breakpoint debugging.
135 
136  virtual OsStatus setPriority(int priority) = 0;
137  //:Set the priority of the task
138  // Priorities range from 0, the highest priority, to 255, the lowest
139  // priority.
140 
141  virtual void setUserData(int data);
142  //:Set the userData for the task.
143  // The class does not use this information itself, but merely stores
144  // it on behalf of the caller.
145 
146  virtual OsStatus varAdd(int* pVar) = 0;
147  //:Add a task variable to the task
148  // This routine adds a specified variable pVar (4-byte memory
149  // location) to its task's context. After calling this routine, the
150  // variable is private to the task. The task can access and modify
151  // the variable, but the modifications are not visible to other tasks,
152  // and other tasks' modifications to that variable do not affect the
153  // value seen by the task. This is accomplished by saving and restoring
154  // the variable's value each time a task switch occurs to or from the
155  // calling task.
156 
157  virtual OsStatus varDelete(int* pVar) = 0;
158  //:Remove a task variable from the task
159  // This routine removes a specified task variable, pVar, from its
160  // task's context. The private value of that variable is lost.
161 
162  virtual OsStatus varSet(int* pVar, int value) = 0;
163  //:Set the value of a private task variable
164  // This routine sets the private value of the task variable for a
165  // specified task. The specified task is usually not the calling task,
166  // which can set its private value by directly modifying the variable.
167  // This routine is provided primarily for debugging purposes.
168 
169  virtual OsStatus syslog(const OsSysLogFacility facility,
170  const OsSysLogPriority priority,
171  const char* format,
172  ...)
173 #ifdef __GNUC__
174  // with the -Wformat switch, this enables format string checking
175  __attribute__ ((format(printf, 4, 5)))
176 #endif
177  ;
178 
179  //:Adds a syslog entry to the system logger.
180  //
182  // event. See the OsSysLogFacility for more information.
184  // OsSysLogPriority for more information.
185 
186  static OsStatus delay(const int milliSecs);
187  //:Delay a task from executing for the specified number of milliseconds
188  // This routine causes the calling task to relinquish the CPU for the
189  // duration specified. This is commonly referred to as manual
190  // rescheduling, but it is also useful when waiting for some external
191  // condition that does not have an interrupt associated with it.
192 
193  static OsStatus safe(void);
194  //:Make the calling task safe from deletion
195  // This routine protects the calling task from deletion. Tasks that
196  // attempt to delete a protected task will block until the task is
197  // made unsafe, using unsafe(). When a task becomes unsafe, the
198  // deleter will be unblocked and allowed to delete the task.
199  // The safe() primitive utilizes a count to keep track of
200  // nested calls for task protection. When nesting occurs,
201  // the task becomes unsafe only after the outermost unsafe()
202  // is executed.
203 
204  static OsStatus unsafe(void);
205  //:Make the calling task unsafe from deletion
206  // This routine removes the calling task's protection from deletion.
207  // Tasks that attempt to delete a protected task will block until the
208  // task is unsafe. When a task becomes unsafe, the deleter will be
209  // unblocked and allowed to delete the task.
210  // The unsafe() primitive utilizes a count to keep track of nested
211  // calls for task protection. When nesting occurs, the task becomes
212  // unsafe only after the outermost unsafe() is executed.
213 
214  static void yield(void);
215  //:Yield the CPU if a task of equal or higher priority is ready to run
216 
217 /* ============================ ACCESSORS ================================= */
218 
219  static OsTaskBase* getCurrentTask(void);
220  //:Return a pointer to the OsTask object for the currently executing task
221  // Return NULL if none exists.
222 
223  static OsStatus getCurrentTaskId(int &rid);
224  //:Return an Id of the currently executing task
225  // This Id is unique within the current process, but not necessarily
226  // over the entire host.
227  // Any two simultaneous executions that share their memory space
228  // will have different values from getCurrentTaskId().
229 
230  static OsTaskBase* getTaskByName(const UtlString& taskName);
231  //:Return a pointer to the OsTask object corresponding to the named task
232  // Return NULL if there is no task object with that name.
233 
234  static OsTaskBase* getTaskById(const int taskId);
235  //:Return a pointer to the OsTask object corresponding to taskId
236  // Return NULL is there is no task object with that id.
237 
238  virtual void* getArg(void);
239  //:Get the void* value passed as an argument to the task
240 
241  virtual OsStatus getErrno(int& rErrno) = 0;
242  //:Get the errno status for the task
243 
244  virtual const UtlString& getName(void);
245  //:Get the name associated with the task
246 
247  virtual int getOptions(void) = 0;
248  //:Return the execution options for the task
249 
250  virtual OsStatus getPriority(int& rPriority) = 0;
251  //:Return the priority of the task
252 
253  virtual int getUserData(void);
254  //:Return the userData for the task.
255 
256  virtual OsStatus varGet(void) = 0;
257  //:Get the value of a task variable
258  // This routine returns the private value of a task variable for its
259  // task. The task is usually not the calling task, which can get its
260  // private value by directly accessing the variable. This routine is
261  // provided primarily for debugging purposes.
262 
263 /* ============================ INQUIRY =================================== */
264 
265  virtual OsStatus id(OsTaskId_t &rId) = 0;
266  //:Get the task ID for this task
267 
268  virtual UtlBoolean isReady(void);
269  //:Check if the task is running
270  // Return TRUE is the task is started and not suspended, otherwise FALSE.
271 
272  virtual UtlBoolean isShutDown(void);
273  //:Return TRUE if a task shutdown has been requested and acknowledged
274 
275  virtual UtlBoolean isShuttingDown(void);
276  //:Return TRUE if a task shutdown has been requested but not acknowledged
277 
278  virtual UtlBoolean isStarted(void);
279  //:Return TRUE if the task has been started (and has not been shut down)
280 
281  virtual UtlBoolean isSuspended(void) = 0;
282  //:Check if the task is suspended
283  // Return TRUE is the task is suspended, otherwise FALSE.
284 
285  virtual UtlBoolean isUnInitialized(void);
286  //:Return TRUE if a task is un-initialized
287 
288 
289 /* //////////////////////////// PROTECTED ///////////////////////////////// */
290 protected:
291  OsMutex mDataGuard; // Mutex guard to protect the OsTask internal data
292  UtlString mName; // global name associated with the task
293 
294  volatile TaskState mState; // Task object state
295 
296  OsTaskBase(const UtlString& name,
297  void* pArg,
298  const int priority,
299  const int options,
300  const int stackSize);
301  //:Constructor
302 
303  virtual
304  ~OsTaskBase();
305  //:Destructor
306 
307  virtual int run(void* pArg) = 0;
308  //:The entry point for the task
309  // Derive new tasks as subclasses of OsTask, overriding this method.
310 
311  virtual UtlBoolean waitUntilShutDown(int milliSecToWait = 20000);
312  //: Wait until the task is shut down and the run method has exited.
313  // Most subclasses of OsTask should call this method in
314  // the destructor before deleting any members which are
315  // accessed by the run method.
316 
317  virtual void ackShutdown(void);
318  //:Acknowledge a shutdown request
319  // This method should only be called by OS specific derived, concrete thread
320  // classes in the threadEntry() static method that invoked the run method.
321  // The point of this method is to signal that no member variables are accessed
322  // by the run() method and that the run method has exited such that it is now
323  // safe to delete this class. For this reason this method must be called
324  // AFTER run exits (not within). Related to this handshake/signaling is
325  // the waitUntilShutDown() method. The waitUntilShutDown() MUST be called by
326  // the destructors of all classes derived from OsTask. waitUntilShutDown()
327  // should be the first thing invoked in the destructor before any members
328  // are destructed.
329 
330 
331 /* //////////////////////////// PRIVATE /////////////////////////////////// */
332 private:
333 
334  void* mpArg; // argument passed to the task
335  int mUserData; // data stored on behalf of the user. This data
336  // is read/written via getUserData()/setUserData()
337 
338  OsTaskBase(const OsTaskBase& rOsTask);
339  //:Copy constructor (not implemented for this class)
340 
341  OsTaskBase& operator=(const OsTaskBase& rhs);
342  //:Assignment operator (not implemented for this class)
343 
344 
345 };
346 
347 /* ============================ INLINE METHODS ============================ */
348 
349 // Depending on the native OS that we are running on, we include the class
350 // declaration for the appropriate lower level implementation and use a
351 // "typedef" statement to associate the OS-independent class name (OsTask)
352 // with the OS-dependent realization of that type (e.g., OsTaskWnt).
353 #if defined(_WIN32)
354 # include "os/Wnt/OsTaskWnt.h"
355  typedef class OsTaskWnt OsTask;
356 #elif defined(_VXWORKS)
357 # include "os/Vxw/OsTaskVxw.h"
358  typedef class OsTaskVxw OsTask;
359 #elif defined(__pingtel_on_posix__)
360 # include "os/linux/OsTaskLinux.h"
361  typedef class OsTaskLinux OsTask;
362 #else
363 # error Unsupported target platform.
364 #endif
365 
366 #endif // _OsTask_h_
Definition: OsTask.h:79
static const UtlString TASK_PREFIX
Definition: OsTask.h:67
Definition: OsTask.h:76
virtual int getOptions(void)=0
virtual UtlBoolean start(void)=0
enum tagOsSysLogFacility OsSysLogFacility
enumcode: FAC_PERF - performance related enumcode: FAC_KERNEL - kernel/os related enumcode: FAC_AUTH ...
Definition: OsSysLogFacilities.h:140
virtual UtlBoolean restart(void)=0
virtual OsStatus varGet(void)=0
virtual UtlBoolean isUnInitialized(void)
Definition: OsTask.cpp:160
virtual void setUserData(int data)
Definition: OsTask.cpp:66
static OsTaskBase * getTaskByName(const UtlString &taskName)
Definition: OsTask.h:78
OsStatus
Definition: OsStatus.h:27
static const int DEF_PRIO
Definition: OsTask.h:65
virtual OsStatus varDelete(int *pVar)=0
virtual OsStatus syslog(const OsSysLogFacility facility, const OsSysLogPriority priority, const char *format,...)
Definition: OsTask.cpp:72
Definition: OsTask.h:59
Definition: OsTaskLinux.h:50
OsMutex mDataGuard
Definition: OsTask.h:291
static OsStatus delay(const int milliSecs)
param: facility - Defines the facility responsible for adding the
Definition: OsTask.cpp:120
Definition: OsAtomics.h:47
Definition: UtlString.h:48
virtual OsStatus deleteForce(void)=0
enumcode: UNINITIALIZED - no low-level task, no name DB entries enumcode: STARTED - low-level task an...
Definition: OsTask.h:77
virtual int run(void *pArg)=0
virtual UtlBoolean isStarted(void)
Definition: OsTask.cpp:153
int errno
virtual OsStatus setPriority(int priority)=0
virtual OsStatus id(OsTaskId_t &rId)=0
virtual OsStatus setOptions(int options)=0
virtual UtlBoolean isShutDown(void)
Definition: OsTask.cpp:138
virtual OsStatus resume(void)=0
enum tagOsSysLogPriority OsSysLogPriority
virtual UtlBoolean isSuspended(void)=0
virtual OsStatus setErrno(int errno)=0
static const int DEF_OPTIONS
Definition: OsTask.h:64
volatile TaskState mState
Definition: OsTask.h:294
virtual void * getArg(void)
Definition: OsTask.cpp:98
virtual void requestShutdown(void)
Definition: OsTask.cpp:53
TaskState
Definition: OsTask.h:74
virtual OsStatus getErrno(int &rErrno)=0
virtual UtlBoolean waitUntilShutDown(int milliSecToWait=20000)
Definition: OsTask.cpp:212
virtual UtlBoolean isReady(void)
Definition: OsTask.cpp:128
static OsStatus getCurrentTaskId(int &rid)
static OsTaskBase * getCurrentTask(void)
Definition: OsTime.h:37
virtual OsStatus varAdd(int *pVar)=0
static const UtlString TASKID_PREFIX
Definition: OsTask.h:69
virtual ~OsTaskBase()
Definition: OsTask.cpp:191
int UtlBoolean
Definition: UtlDefs.h:41
static OsStatus safe(void)
virtual OsStatus suspend(void)=0
OsTaskBase(const UtlString &name, void *pArg, const int priority, const int options, const int stackSize)
Definition: OsTask.cpp:170
static const int DEF_STACKSIZE
Definition: OsTask.h:66
virtual int getUserData(void)
Definition: OsTask.cpp:110
virtual const UtlString & getName(void)
Definition: OsTask.cpp:104
virtual void ackShutdown(void)
Definition: OsTask.cpp:267
static void yield(void)
Definition: OsTask.cpp:115
Definition: OsTaskWnt.h:57
static OsAtomicInt taskCount
Definition: OsTask.h:72
virtual OsStatus varSet(int *pVar, int value)=0
UtlString mName
Definition: OsTask.h:292
virtual UtlBoolean isShuttingDown(void)
Definition: OsTask.cpp:145
virtual OsStatus getPriority(int &rPriority)=0
static OsStatus unsafe(void)
static OsTaskBase * getTaskById(const int taskId)