Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | File List | Namespace Members | Class Members | File Members | Related Pages

wvtask.h

Go to the documentation of this file.
00001 /* -*- Mode: C++ -*- 00002 * Worldvisions Weaver Software: 00003 * Copyright (C) 1997-2002 Net Integration Technologies, Inc. 00004 * 00005 * A set of classes that provide co-operative multitasking support. By 00006 * default there's no scheduler -- you have to provide it yourself. As it 00007 * stands, this is just a convenient way to switch from one context to 00008 * another when you know exactly what you want to do. 00009 * 00010 * This is mainly intended for use by WvStream, but that's probably not the 00011 * only possible use... see also WvCont. 00012 */ 00013 #ifndef __WVTASK_H 00014 #define __WVTASK_H 00015 00016 #ifdef _WIN32 00017 00018 #include "wvwin32task.h" 00019 00020 #else 00021 00022 #include "wvstring.h" 00023 #include "wvlinklist.h" 00024 #include "setjmp.h" 00025 00026 #define WVTASK_MAGIC 0x123678 00027 00028 class WvTaskMan; 00029 00030 /** Represents a single thread of control. */ 00031 class WvTask 00032 { 00033 friend class WvTaskMan; 00034 00035 // you might think it would be useful to have this return an int, since 00036 // yield() and run() both return int. But that ends up being more 00037 // confusing than you think, because if you call task1->run(), and he 00038 // calls task2->run(), and task2 calls yield(), then task1->run() returns 00039 // the value *task2* passed to yield! So we avoid the confusion by not 00040 // using return values here, which discourages people from thinking of 00041 // them as return values. 00042 typedef void TaskFunc(void *userdata); 00043 00044 static int taskcount, numtasks, numrunning; 00045 int magic_number, *stack_magic; 00046 WvString name; 00047 int tid; 00048 00049 size_t stacksize; 00050 bool running, recycled; 00051 00052 WvTaskMan &man; 00053 jmp_buf mystate; // used for resuming the task 00054 00055 TaskFunc *func; 00056 void *userdata; 00057 00058 WvTask(WvTaskMan &_man, size_t _stacksize = 64*1024); 00059 00060 public: 00061 virtual ~WvTask(); 00062 00063 void start(WvStringParm _name, TaskFunc *_func, void *_userdata); 00064 bool isrunning() const 00065 { return running; } 00066 void recycle(); 00067 }; 00068 00069 00070 DeclareWvList(WvTask); 00071 00072 /** Provides co-operative multitasking support among WvTask instances. */ 00073 class WvTaskMan 00074 { 00075 friend class WvTask; 00076 00077 static WvTaskMan *singleton; 00078 static int links; 00079 00080 static int magic_number; 00081 static WvTaskList free_tasks; 00082 00083 static void get_stack(WvTask &task, size_t size); 00084 static void stackmaster(); 00085 static void _stackmaster(); 00086 static void do_task(); 00087 00088 static char *stacktop; 00089 static jmp_buf stackmaster_task; 00090 00091 static WvTask *stack_target; 00092 static jmp_buf get_stack_return; 00093 00094 static WvTask *current_task; 00095 static jmp_buf toplevel; 00096 00097 WvTaskMan(); 00098 virtual ~WvTaskMan(); 00099 00100 public: 00101 /// get/dereference the singleton global WvTaskMan 00102 static WvTaskMan *get(); 00103 static void unlink(); 00104 00105 WvTask *start(WvStringParm name, 00106 WvTask::TaskFunc *func, void *userdata, 00107 size_t stacksize = 64*1024); 00108 00109 // run() and yield() return the 'val' passed to run() when this task 00110 // was started. 00111 static int run(WvTask &task, int val = 1); 00112 static int yield(int val = 1); 00113 00114 static WvTask *whoami() 00115 { return current_task; } 00116 }; 00117 00118 00119 #endif // ifdef _WIN32 00120 #endif // __WVTASK_H

Generated on Tue Oct 5 01:09:21 2004 for WvStreams by doxygen 1.3.7