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;
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)
256 data->ret = data->cb(data->p1);
A WvFastString acts exactly like a WvString, but can take (const char *) strings without needing to a...
void rewind()
Rewinds the iterator to make it point to an imaginary element preceeding the first element of the lis...
Represents a single thread of control.
WvCont provides "continuations", which are apparently also known as semi-coroutines.
static WvTaskMan * get()
get/dereference the singleton global WvTaskMan
WvLink * next()
Moves the iterator along the list to point to the next element.
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.
static bool isok()
Tell us if the current context is "okay", that is, not trying to die.
A linked list container class.
The iterator type for linked lists.
WvString is an implementation of a simple and efficient printable-string class.
static void * yield(void *ret=0)
"return" from the current callback, giving value 'ret' to the person who called us.
Provides co-operative multitasking support among WvTask instances.
static WvCont current()
Get a copy of the current WvCont.
void * operator()(void *p1=0)
call the callback, making p1 the return value of yield() or the parameter to the function, and returning Ret, the argument of yield() or the return value of the function.