WvStreams
wvcont.h
00001 /* -*- Mode: C++ -*-
00002  * Worldvisions Weaver Software:
00003  *   Copyright (C) 1997-2002 Net Integration Technologies, Inc.
00004  *
00005  * FIXME: I was too lazy to templatize this properly, so we only support
00006  * WvCallback<void*,void*>.  It should be possible to work with any kind
00007  * of return value and parameter, although it makes sense to limit things
00008  * to just one parameter (since it currently has to be returned by yield()
00009  * somehow).
00010  */
00011 
00012 #ifndef __WVCONT_H
00013 #define __WVCONT_H
00014 
00015 #include "wvlinklist.h"
00016 #include "wvstreamsdebugger.h"
00017 #include "wvtr1.h"
00018 
00019 typedef wv::function<void*(void*)> WvContCallback;
00020 
00029 class WvCont
00030 {
00031     struct Data;
00032     friend struct Data;
00033     typedef WvList<Data> DataList;
00034     
00035 private:
00041     Data *data;
00042     static DataList *data_list;
00043 
00044     static Data *curdata;
00045     static int taskdepth;
00046     
00047     static void bouncer(void *userdata);
00048     
00053     void *call()
00054         { return _call(data); }
00055     
00060     static void *_call(Data *data);
00061 
00066     WvCont(Data *data);
00067 
00068 public:
00074     WvCont(const WvContCallback &cb, unsigned long stacksize = 64*1024);
00075     
00077     WvCont(const WvCont &cb);
00078     
00080     ~WvCont();
00081     
00087     void *operator() (void *p1 = 0);
00088     
00089     // the following are static because a function doesn't really know
00090     // which WvCont it belongs to, and only one WvCont can be the "current"
00091     // one globally in an application anyway.
00092     // 
00093     // Unfortunately this prevents us from assert()ing that you're in the
00094     // context you think you are.
00095     
00099     static WvCont current();
00100 
00107     static void *yield(void *ret = 0);
00108     
00114     static bool isok();
00115 
00116     
00130     template <typename R, typename T>
00131         static R c_bouncer(T t, void *_cont)
00132         {
00133             WvCont &cont = *(WvCont *)_cont;
00134             return (R)cont((T)t);
00135         }
00136 
00137 
00151     template <typename R>
00152      static R c_bouncer(void *_cont)
00153         {
00154             WvCont &cont = *(WvCont *)_cont;
00155             return (R)cont(0);
00156         }
00157 
00158 private:
00159     static WvString debugger_conts_run_cb(WvStringParm cmd, WvStringList &args,
00160         WvStreamsDebugger::ResultCallback result_cb, void *);
00161 };
00162 
00163 #endif // __WVCONT_H
00164