10#include "wvlinklist.h"
28 Data(
const WvContCallback &_cb,
size_t _stacksize) : cb(_cb)
29 { links = 1; finishing =
false; stacksize = _stacksize; mydepth = 0;
31 task = NULL; report();
32 if (data_list == NULL)
33 data_list =
new DataList;
34 data_list->append(
this,
false);
39 { links++; report(); }
41 { links--; report();
if (!links)
delete this; }
49int WvCont::taskdepth = 0;
52WvCont::DataList *WvCont::data_list = NULL;
55WvCont::WvCont(
const WvCont &cb)
57 static bool first =
true;
61 WvStreamsDebugger::add_command(
"conts", 0,
62 debugger_conts_run_cb, 0);
70WvCont::WvCont(
const WvContCallback &cb,
unsigned long _stacksize)
72 data =
new Data(cb, (
size_t)_stacksize);
76WvCont::WvCont(Data *data)
87 data->finishing =
true;
89 while (data->task && data->task->isrunning())
107 data_list->unlink(
this);
108 if (data_list->isempty())
116static inline const char *Yes_No(
bool val)
118 return val?
"Yes":
"No";
122WvString WvCont::debugger_conts_run_cb(WvStringParm cmd, WvStringList &args,
123 WvStreamsDebugger::ResultCallback result_cb,
void *)
125 const char *format =
"%5s%s%5s%s%9s%s%10s%s%7s%s%s";
127 result.append(format,
"Links",
"-",
"Depth",
"-",
"Finishing",
"-",
"Stack Size",
128 "-",
"Task ID",
"-",
"Task Name------");
129 result_cb(cmd, result);
132 return WvString::null;
134 DataList::Iter i(*data_list);
135 for (i.rewind(); i.next(); )
138 result.append(format,
139 i->links,
" ", i->mydepth,
" ", Yes_No(i->finishing),
" ",
141 i->task? WvString(i->task->get_tid()): WvString(
"n/a"),
" ",
142 i->task? i->task->get_name(): WvString(
"n/a"));
143 result_cb(cmd, result);
146 return WvString::null;
151void *WvCont::_call(
Data *data)
153 Data *olddata = curdata;
169 assert(!data->mydepth);
170 data->mydepth = ++taskdepth;
176 data->taskman->run(*data->task);
177 if (data->links == 1)
179 data->finishing =
true;
182 }
while (data->finishing && data->task && data->task->isrunning());
184 }
while (taskdepth > data->mydepth);
185 assert(taskdepth == data->mydepth);
189 void *ret = data->ret;
198 data->ret =
reinterpret_cast<void*
>(-42);
201 data->task = data->taskman->start(
"wvcont", bouncer, data,
203 else if (!data->task->isrunning())
204 data->task->start(
"wvcont+", bouncer, data);
216 assert(curdata->task == curdata->taskman->whoami());
218 return WvCont(curdata);
225 assert(curdata->task == curdata->taskman->whoami());
233 curdata->taskman->yield();
244 assert(curdata->task == curdata->taskman->whoami());
245 return !curdata->finishing;
249void WvCont::bouncer(
void *userdata)
251 Data *data = (Data *)userdata;
256 data->ret = data->cb(data->p1);
static WvCont current()
Get a copy of the current WvCont.
static void * yield(void *ret=0)
"return" from the current callback, giving value 'ret' to the person who called us.
static bool isok()
Tell us if the current context is "okay", that is, not trying to die.
void * operator()(void *p1=0)
call the callback, making p1 the return value of yield() or the parameter to the function,...
Provides co-operative multitasking support among WvTask instances.
static WvTaskMan * get()
get/dereference the singleton global WvTaskMan
Represents a single thread of control.