6 #define WIN32_LEAN_AND_MEAN
9 #define _WIN32_WINNT 0x0400
14 #include "wvwin32task.h"
21 int WvTask::taskcount, WvTask::numtasks, WvTask::numrunning;
24 int WvTaskMan::links = 1;
26 int WvTaskMan::magic_number;
27 WvTaskList WvTaskMan::free_tasks;
29 WvTask *WvTaskMan::stack_target;
31 WvTask *WvTaskMan::current_task;
32 LPVOID WvTaskMan::toplevel;
34 WvTask::WvTask(
WvTaskMan &_man,
size_t _stacksize) : man(_man)
36 stacksize = _stacksize;
37 running = recycled =
false;
43 magic_number = WVTASK_MAGIC;
46 mystate = CreateFiber(_stacksize, &MyFiberProc,
this);
59 VOID CALLBACK WvTask::MyFiberProc(PVOID lpParameter)
64 if (_this->func && _this->running)
66 _this->func(_this->userdata);
70 _this->running =
false;
77 void WvTask::start(WvStringParm _name, TaskFunc *_func,
void *_userdata)
88 void WvTask::recycle()
92 if (!running && !recycled)
94 man.free_tasks.append(
this,
true);
108 void WvTaskMan::unlink()
118 WvTaskMan::WvTaskMan()
122 magic_number = -WVTASK_MAGIC;
124 toplevel = ::ConvertThreadToFiber(0);
129 WvTaskMan::~WvTaskMan()
135 WvTask *WvTaskMan::start(WvStringParm name,
136 WvTask::TaskFunc *func,
void *userdata,
141 WvTaskList::Iter i(free_tasks);
142 for (i.rewind(); i.next(); )
144 if (i().stacksize >= stacksize)
147 i.link->set_autofree(
false);
150 t->start(name, func, userdata);
155 t =
new WvTask(*
this, stacksize);
156 t->start(name, func, userdata);
161 int WvTaskMan::run(
WvTask &task,
int val)
163 assert(magic_number == -WVTASK_MAGIC);
164 assert(task.magic_number == WVTASK_MAGIC);
165 assert(!task.recycled);
167 if (&task == current_task)
170 WvTask *old_task = current_task;
171 current_task = &task;
177 state = &old_task->mystate;
180 ::SwitchToFiber(task.mystate);
184 current_task = old_task;
190 int WvTaskMan::yield(
int val)
195 WvTask *task = current_task;
198 ::SwitchToFiber(toplevel);
200 assert(current_task == task);