Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | File List | Namespace Members | Class Members | File Members | Related Pages

wvcont.h

Go to the documentation of this file.
00001 /* -*- Mode: C++ -*-
00002  * Worldvisions Weaver Software:
00003  *   Copyright (C) 1997-2002 Net Integration Technologies, Inc.
00004  *
00005  * WvCont provides "continuations", which are apparently also known as
00006  * semi-coroutines.  You can wrap any WvCallback<void*,void*> in a WvCont
00007  * and make it a "continuable" callback - that is, you can yield() from it
00008  * and return a value.  Next time someone calls your callback, it will be
00009  * as if yield() has returned (and the parameter to your function is returned
00010  * from yield()).
00011  * 
00012  * FIXME: I was too lazy to templatize this properly, so we only support
00013  * WvCallback<void*,void*>.  It should be possible to work with any kind
00014  * of return value and parameter, although it makes sense to limit things
00015  * to just one parameter (since it currently has to be returned by yield()
00016  * somehow).
00017  */
00018 #ifndef __WVCONT_H
00019 #define __WVCONT_H
00020 
00021 #include "wvcallback.h"
00022 
00023 class WvCont
00024 {
00025 public:
00026     /**
00027      * These are hardcoded because I'm too lazy to templatize this.
00028      * Most people will ignore the return and parameter values anyhow.
00029      */
00030     typedef void *R;
00031     typedef void *P1;
00032 
00033     typedef WvCallback<R, P1> Callback;
00034     
00035 private:
00036     /**
00037      * When we copy a WvCont, we increase the reference count of the 'data'
00038      * member rather than copying it.  That makes it so every copy of a given
00039      * callback object still refers to the same WvTask.
00040      */
00041     struct Data;
00042     Data *data;
00043 
00044     static Data *curdata;
00045     static int taskdepth;
00046     
00047     static void bouncer(void *userdata);
00048     
00049     /**
00050      * Actually call the callback inside its task, and enforce a call stack.
00051      * Doesn't do anything with arguments or return values.
00052      */
00053     void call();
00054 
00055     WvCont(Data *data);
00056 
00057 public:
00058     /**
00059      * Construct a WvCont using an existing WvCallback.  The WvCont object
00060      * can be used in place of that callback, and stored in a callback of
00061      * the same data type.
00062      */
00063     WvCont(const Callback &cb, unsigned long stacksize = 64*1024);
00064     
00065     /** Copy constructor. */
00066     WvCont(const WvCont &cb);
00067     
00068     /** Destructor. */
00069     ~WvCont();
00070     
00071     /**
00072      * call the callback, making p1 the return value of yield() or the
00073      * parameter to the function, and returning Ret, the argument of yield()
00074      * or the return value of the function.
00075      */
00076     R operator() (P1 p1 = 0);
00077     
00078     // the following are static because a function doesn't really know
00079     // which WvCont it belongs to, and only one WvCont can be the "current"
00080     // one globally in an application anyway.
00081     // 
00082     // Unfortunately this prevents us from assert()ing that you're in the
00083     // context you think you are.
00084     
00085     /**
00086      * Get a copy of the current WvCont.
00087      */
00088     static WvCont current();
00089 
00090     /**
00091      * "return" from the current callback, giving value 'ret' to the person
00092      * who called us.  Next time this callback is called, it's as if yield()
00093      * had returned, and the parameter to the callback is the value of
00094      * yield().
00095      */
00096     static P1 yield(R ret = 0);
00097     
00098     /**
00099      * Tell us if the current context is "okay", that is, not trying to
00100      * die. If !isok(), you shouldn't yield(), because the caller is just
00101      * going to keep calling you until you die.  Return as soon as you can.
00102      */
00103     static bool isok();
00104 };
00105 
00106 #endif // __WVCONT_H
00107 

Generated on Sat Feb 21 21:05:26 2004 for WvStreams by doxygen 1.3.5