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)
34 data_list->
append(
this,
false);
39 { links++; report(); }
41 { links--; report();
if (!links)
delete this; }
49 int WvCont::taskdepth = 0;
57 static bool first =
true;
61 WvStreamsDebugger::add_command(
"conts", 0,
62 debugger_conts_run_cb, 0);
70 WvCont::WvCont(
const WvContCallback &cb,
unsigned long _stacksize)
72 data =
new Data(cb, (
size_t)_stacksize);
76 WvCont::WvCont(Data *data)
87 data->finishing =
true;
89 while (data->task && data->task->isrunning())
107 data_list->unlink(
this);
108 if (data_list->isempty())
116 static inline const char *Yes_No(
bool val)
118 return val?
"Yes":
"No";
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),
" ",
142 i->task? i->task->get_name():
WvString(
"n/a"));
143 result_cb(cmd, result);
146 return WvString::null;
151 void *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());
225 assert(curdata->task == curdata->taskman->whoami());
233 curdata->taskman->yield();
244 assert(curdata->task == curdata->taskman->whoami());
245 return !curdata->finishing;
249 void WvCont::bouncer(
void *userdata)
251 Data *data = (Data *)userdata;
256 data->ret = data->cb(data->p1);
WvCont provides "continuations", which are apparently also known as semi-coroutines.
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,...
A WvFastString acts exactly like a WvString, but can take (const char *) strings without needing to a...
A linked list container class.
void append(T *data, bool autofree, const char *id=NULL)
Appends the element to the end of the list.
This is a WvList of WvStrings, and is a really handy way to parse strings.
WvString is an implementation of a simple and efficient printable-string class.
Provides co-operative multitasking support among WvTask instances.
static WvTaskMan * get()
get/dereference the singleton global WvTaskMan
Represents a single thread of control.