From b262ded7e0cf21314524bf702b0e4fe28a3c3060 Mon Sep 17 00:00:00 2001
From: Nat Goodspeed <nat@lindenlab.com>
Date: Wed, 1 Jul 2015 18:33:29 -0400
Subject: MAINT-5351: Remove 'self' parameter from coroutine functions.
 lleventcoro_test.cpp runs clean (as modified for new API), and all the rest
 builds clean, but the resulting viewer is as yet untested.

---
 indra/llcommon/tests/lleventcoro_test.cpp | 174 +++++++++++-------------------
 1 file changed, 64 insertions(+), 110 deletions(-)

(limited to 'indra/llcommon/tests')

diff --git a/indra/llcommon/tests/lleventcoro_test.cpp b/indra/llcommon/tests/lleventcoro_test.cpp
index 2096807e53..31e9856477 100755
--- a/indra/llcommon/tests/lleventcoro_test.cpp
+++ b/indra/llcommon/tests/lleventcoro_test.cpp
@@ -82,6 +82,7 @@
 #include "llevents.h"
 #include "tests/wrapllerrs.h"
 #include "stringize.h"
+#include "llcoros.h"
 #include "lleventcoro.h"
 #include "../test/debug.h"
 
@@ -121,9 +122,6 @@ typedef coroutine<std::string::iterator(void)> match_coroutine_type;
 /*****************************************************************************
 *   Test helpers
 *****************************************************************************/
-// I suspect this will be typical of coroutines used in Linden software
-typedef boost::dcoroutines::coroutine<void()> coroutine_type;
-
 /// Simulate an event API whose response is immediate: sent on receipt of the
 /// initial request, rather than after some delay. This is the case that
 /// distinguishes postAndWait() from calling post(), then calling
@@ -166,7 +164,7 @@ namespace tut
     {
         // Define coroutine bodies as methods here so they can use ensure*()
 
-        void explicit_wait(coroutine_type::self& self)
+        void explicit_wait(boost::dcoroutines::coroutine<void()>::self& self)
         {
             BEGIN
             {
@@ -187,20 +185,20 @@ namespace tut
             END
         }
 
-        void waitForEventOn1(coroutine_type::self& self)
+        void waitForEventOn1()
         {
             BEGIN
             {
-                result = waitForEventOn(self, "source");
+                result = waitForEventOn("source");
             }
             END
         }
 
-        void waitForEventOn2(coroutine_type::self& self)
+        void waitForEventOn2()
         {
             BEGIN
             {
-                LLEventWithID pair = waitForEventOn(self, "reply", "error");
+                LLEventWithID pair = waitForEventOn("reply", "error");
                 result = pair.first;
                 which  = pair.second;
                 debug(STRINGIZE("result = " << result << ", which = " << which));
@@ -208,12 +206,11 @@ namespace tut
             END
         }
 
-        void postAndWait1(coroutine_type::self& self)
+        void postAndWait1()
         {
             BEGIN
             {
-                result = postAndWait(self,
-                                     LLSDMap("value", 17),       // request event
+                result = postAndWait(LLSDMap("value", 17),       // request event
                                      immediateAPI.getPump(),     // requestPump
                                      "reply1",                   // replyPump
                                      "reply");                   // request["reply"] = name
@@ -221,12 +218,11 @@ namespace tut
             END
         }
 
-        void postAndWait2(coroutine_type::self& self)
+        void postAndWait2()
         {
             BEGIN
             {
-                LLEventWithID pair = ::postAndWait2(self,
-                                                    LLSDMap("value", 18),
+                LLEventWithID pair = ::postAndWait2(LLSDMap("value", 18),
                                                     immediateAPI.getPump(),
                                                     "reply2",
                                                     "error2",
@@ -239,12 +235,11 @@ namespace tut
             END
         }
 
-        void postAndWait2_1(coroutine_type::self& self)
+        void postAndWait2_1()
         {
             BEGIN
             {
-                LLEventWithID pair = ::postAndWait2(self,
-                                                    LLSDMap("value", 18)("fail", LLSD()),
+                LLEventWithID pair = ::postAndWait2(LLSDMap("value", 18)("fail", LLSD()),
                                                     immediateAPI.getPump(),
                                                     "reply2",
                                                     "error2",
@@ -257,55 +252,55 @@ namespace tut
             END
         }
 
-        void coroPump(coroutine_type::self& self)
+        void coroPump()
         {
             BEGIN
             {
                 LLCoroEventPump waiter;
                 replyName = waiter.getName();
-                result = waiter.wait(self);
+                result = waiter.wait();
             }
             END
         }
 
-        void coroPumpPost(coroutine_type::self& self)
+        void coroPumpPost()
         {
             BEGIN
             {
                 LLCoroEventPump waiter;
-                result = waiter.postAndWait(self, LLSDMap("value", 17),
+                result = waiter.postAndWait(LLSDMap("value", 17),
                                             immediateAPI.getPump(), "reply");
             }
             END
         }
 
-        void coroPumps(coroutine_type::self& self)
+        void coroPumps()
         {
             BEGIN
             {
                 LLCoroEventPumps waiter;
                 replyName = waiter.getName0();
                 errorName = waiter.getName1();
-                LLEventWithID pair(waiter.wait(self));
+                LLEventWithID pair(waiter.wait());
                 result = pair.first;
                 which  = pair.second;
             }
             END
         }
 
-        void coroPumpsNoEx(coroutine_type::self& self)
+        void coroPumpsNoEx()
         {
             BEGIN
             {
                 LLCoroEventPumps waiter;
                 replyName = waiter.getName0();
                 errorName = waiter.getName1();
-                result = waiter.waitWithException(self);
+                result = waiter.waitWithException();
             }
             END
         }
 
-        void coroPumpsEx(coroutine_type::self& self)
+        void coroPumpsEx()
         {
             BEGIN
             {
@@ -314,7 +309,7 @@ namespace tut
                 errorName = waiter.getName1();
                 try
                 {
-                    result = waiter.waitWithException(self);
+                    result = waiter.waitWithException();
                     debug("no exception");
                 }
                 catch (const LLErrorEvent& e)
@@ -326,19 +321,19 @@ namespace tut
             END
         }
 
-        void coroPumpsNoLog(coroutine_type::self& self)
+        void coroPumpsNoLog()
         {
             BEGIN
             {
                 LLCoroEventPumps waiter;
                 replyName = waiter.getName0();
                 errorName = waiter.getName1();
-                result = waiter.waitWithLog(self);
+                result = waiter.waitWithLog();
             }
             END
         }
 
-        void coroPumpsLog(coroutine_type::self& self)
+        void coroPumpsLog()
         {
             BEGIN
             {
@@ -348,7 +343,7 @@ namespace tut
                 WrapLLErrs capture;
                 try
                 {
-                    result = waiter.waitWithLog(self);
+                    result = waiter.waitWithLog();
                     debug("no exception");
                 }
                 catch (const WrapLLErrs::FatalException& e)
@@ -360,12 +355,12 @@ namespace tut
             END
         }
 
-        void coroPumpsPost(coroutine_type::self& self)
+        void coroPumpsPost()
         {
             BEGIN
             {
                 LLCoroEventPumps waiter;
-                LLEventWithID pair(waiter.postAndWait(self, LLSDMap("value", 23),
+                LLEventWithID pair(waiter.postAndWait(LLSDMap("value", 23),
                                                       immediateAPI.getPump(), "reply", "error"));
                 result = pair.first;
                 which  = pair.second;
@@ -373,13 +368,13 @@ namespace tut
             END
         }
 
-        void coroPumpsPost_1(coroutine_type::self& self)
+        void coroPumpsPost_1()
         {
             BEGIN
             {
                 LLCoroEventPumps waiter;
                 LLEventWithID pair(
-                    waiter.postAndWait(self, LLSDMap("value", 23)("fail", LLSD()),
+                    waiter.postAndWait(LLSDMap("value", 23)("fail", LLSD()),
                                        immediateAPI.getPump(), "reply", "error"));
                 result = pair.first;
                 which  = pair.second;
@@ -387,25 +382,25 @@ namespace tut
             END
         }
 
-        void coroPumpsPostNoEx(coroutine_type::self& self)
+        void coroPumpsPostNoEx()
         {
             BEGIN
             {
                 LLCoroEventPumps waiter;
-                result = waiter.postAndWaitWithException(self, LLSDMap("value", 8),
+                result = waiter.postAndWaitWithException(LLSDMap("value", 8),
                                                          immediateAPI.getPump(), "reply", "error");
             }
             END
         }
 
-        void coroPumpsPostEx(coroutine_type::self& self)
+        void coroPumpsPostEx()
         {
             BEGIN
             {
                 LLCoroEventPumps waiter;
                 try
                 {
-                    result = waiter.postAndWaitWithException(self,
+                    result = waiter.postAndWaitWithException(
                         LLSDMap("value", 9)("fail", LLSD()),
                         immediateAPI.getPump(), "reply", "error");
                     debug("no exception");
@@ -419,18 +414,18 @@ namespace tut
             END
         }
 
-        void coroPumpsPostNoLog(coroutine_type::self& self)
+        void coroPumpsPostNoLog()
         {
             BEGIN
             {
                 LLCoroEventPumps waiter;
-                result = waiter.postAndWaitWithLog(self, LLSDMap("value", 30),
+                result = waiter.postAndWaitWithLog(LLSDMap("value", 30),
                                                    immediateAPI.getPump(), "reply", "error");
             }
             END
         }
 
-        void coroPumpsPostLog(coroutine_type::self& self)
+        void coroPumpsPostLog()
         {
             BEGIN
             {
@@ -438,7 +433,7 @@ namespace tut
                 WrapLLErrs capture;
                 try
                 {
-                    result = waiter.postAndWaitWithLog(self,
+                    result = waiter.postAndWaitWithLog(
                         LLSDMap("value", 31)("fail", LLSD()),
                         immediateAPI.getPump(), "reply", "error");
                     debug("no exception");
@@ -452,11 +447,6 @@ namespace tut
             END
         }
 
-        void ensure_done(coroutine_type& coro)
-        {
-            ensure("coroutine complete", ! coro);
-        }
-
         ImmediateAPI immediateAPI;
         std::string replyName, errorName, threw;
         LLSD result, errordata;
@@ -520,7 +510,8 @@ namespace tut
         // Construct the coroutine instance that will run explicit_wait.
         // Pass the ctor a callable that accepts the coroutine_type::self
         // param passed by the library.
-        coroutine_type coro(boost::bind(&coroutine_data::explicit_wait, this, _1));
+        boost::dcoroutines::coroutine<void()>
+        coro(boost::bind(&coroutine_data::explicit_wait, this, _1));
         // Start the coroutine
         coro(std::nothrow);
         // When the coroutine waits for the event pump, it returns here.
@@ -528,7 +519,7 @@ namespace tut
         // Satisfy the wait.
         LLEventPumps::instance().obtain("source").post("received");
         // Now wait for the coroutine to complete.
-        ensure_done(coro);
+        ensure("coroutine complete", ! coro);
         // ensure the coroutine ran and woke up again with the intended result
         ensure_equals(result.asString(), "received");
     }
@@ -538,12 +529,11 @@ namespace tut
     {
         set_test_name("waitForEventOn1");
         DEBUG;
-        coroutine_type coro(boost::bind(&coroutine_data::waitForEventOn1, this, _1));
-        coro(std::nothrow);
+        LLCoros::instance().launch("test<3>",
+                                   boost::bind(&coroutine_data::waitForEventOn1, this));
         debug("about to send");
         LLEventPumps::instance().obtain("source").post("received");
         debug("back from send");
-        ensure_done(coro);
         ensure_equals(result.asString(), "received");
     }
 
@@ -553,12 +543,10 @@ namespace tut
         set_test_name("waitForEventOn2 reply");
         {
         DEBUG;
-        coroutine_type coro(boost::bind(&coroutine_data::waitForEventOn2, this, _1));
-        coro(std::nothrow);
+        LLCoros::instance().launch("test<4>", boost::bind(&coroutine_data::waitForEventOn2, this));
         debug("about to send");
         LLEventPumps::instance().obtain("reply").post("received");
         debug("back from send");
-        ensure_done(coro);
         }
         ensure_equals(result.asString(), "received");
         ensure_equals("which pump", which, 0);
@@ -569,12 +557,10 @@ namespace tut
     {
         set_test_name("waitForEventOn2 error");
         DEBUG;
-        coroutine_type coro(boost::bind(&coroutine_data::waitForEventOn2, this, _1));
-        coro(std::nothrow);
+        LLCoros::instance().launch("test<5>", boost::bind(&coroutine_data::waitForEventOn2, this));
         debug("about to send");
         LLEventPumps::instance().obtain("error").post("badness");
         debug("back from send");
-        ensure_done(coro);
         ensure_equals(result.asString(), "badness");
         ensure_equals("which pump", which, 1);
     }
@@ -584,12 +570,10 @@ namespace tut
     {
         set_test_name("coroPump");
         DEBUG;
-        coroutine_type coro(boost::bind(&coroutine_data::coroPump, this, _1));
-        coro(std::nothrow);
+        LLCoros::instance().launch("test<6>", boost::bind(&coroutine_data::coroPump, this));
         debug("about to send");
         LLEventPumps::instance().obtain(replyName).post("received");
         debug("back from send");
-        ensure_done(coro);
         ensure_equals(result.asString(), "received");
     }
 
@@ -598,12 +582,10 @@ namespace tut
     {
         set_test_name("coroPumps reply");
         DEBUG;
-        coroutine_type coro(boost::bind(&coroutine_data::coroPumps, this, _1));
-        coro(std::nothrow);
+        LLCoros::instance().launch("test<7>", boost::bind(&coroutine_data::coroPumps, this));
         debug("about to send");
         LLEventPumps::instance().obtain(replyName).post("received");
         debug("back from send");
-        ensure_done(coro);
         ensure_equals(result.asString(), "received");
         ensure_equals("which pump", which, 0);
     }
@@ -613,12 +595,10 @@ namespace tut
     {
         set_test_name("coroPumps error");
         DEBUG;
-        coroutine_type coro(boost::bind(&coroutine_data::coroPumps, this, _1));
-        coro(std::nothrow);
+        LLCoros::instance().launch("test<8>", boost::bind(&coroutine_data::coroPumps, this));
         debug("about to send");
         LLEventPumps::instance().obtain(errorName).post("badness");
         debug("back from send");
-        ensure_done(coro);
         ensure_equals(result.asString(), "badness");
         ensure_equals("which pump", which, 1);
     }
@@ -628,12 +608,10 @@ namespace tut
     {
         set_test_name("coroPumpsNoEx");
         DEBUG;
-        coroutine_type coro(boost::bind(&coroutine_data::coroPumpsNoEx, this, _1));
-        coro(std::nothrow);
+        LLCoros::instance().launch("test<9>", boost::bind(&coroutine_data::coroPumpsNoEx, this));
         debug("about to send");
         LLEventPumps::instance().obtain(replyName).post("received");
         debug("back from send");
-        ensure_done(coro);
         ensure_equals(result.asString(), "received");
     }
 
@@ -642,12 +620,10 @@ namespace tut
     {
         set_test_name("coroPumpsEx");
         DEBUG;
-        coroutine_type coro(boost::bind(&coroutine_data::coroPumpsEx, this, _1));
-        coro(std::nothrow);
+        LLCoros::instance().launch("test<10>", boost::bind(&coroutine_data::coroPumpsEx, this));
         debug("about to send");
         LLEventPumps::instance().obtain(errorName).post("badness");
         debug("back from send");
-        ensure_done(coro);
         ensure("no result", result.isUndefined());
         ensure_equals("got error", errordata.asString(), "badness");
     }
@@ -657,12 +633,10 @@ namespace tut
     {
         set_test_name("coroPumpsNoLog");
         DEBUG;
-        coroutine_type coro(boost::bind(&coroutine_data::coroPumpsNoLog, this, _1));
-        coro(std::nothrow);
+        LLCoros::instance().launch("test<11>", boost::bind(&coroutine_data::coroPumpsNoLog, this));
         debug("about to send");
         LLEventPumps::instance().obtain(replyName).post("received");
         debug("back from send");
-        ensure_done(coro);
         ensure_equals(result.asString(), "received");
     }
 
@@ -671,12 +645,10 @@ namespace tut
     {
         set_test_name("coroPumpsLog");
         DEBUG;
-        coroutine_type coro(boost::bind(&coroutine_data::coroPumpsLog, this, _1));
-        coro(std::nothrow);
+        LLCoros::instance().launch("test<12>", boost::bind(&coroutine_data::coroPumpsLog, this));
         debug("about to send");
         LLEventPumps::instance().obtain(errorName).post("badness");
         debug("back from send");
-        ensure_done(coro);
         ensure("no result", result.isUndefined());
         ensure_contains("got error", threw, "badness");
     }
@@ -686,9 +658,7 @@ namespace tut
     {
         set_test_name("postAndWait1");
         DEBUG;
-        coroutine_type coro(boost::bind(&coroutine_data::postAndWait1, this, _1));
-        coro(std::nothrow);
-        ensure_done(coro);
+        LLCoros::instance().launch("test<13>", boost::bind(&coroutine_data::postAndWait1, this));
         ensure_equals(result.asInteger(), 18);
     }
 
@@ -697,9 +667,7 @@ namespace tut
     {
         set_test_name("postAndWait2");
         DEBUG;
-        coroutine_type coro(boost::bind(&coroutine_data::postAndWait2, this, _1));
-        coro(std::nothrow);
-        ensure_done(coro);
+        LLCoros::instance().launch("test<14>", boost::bind(&coroutine_data::postAndWait2, this));
         ensure_equals(result.asInteger(), 19);
         ensure_equals(which, 0);
     }
@@ -709,9 +677,7 @@ namespace tut
     {
         set_test_name("postAndWait2_1");
         DEBUG;
-        coroutine_type coro(boost::bind(&coroutine_data::postAndWait2_1, this, _1));
-        coro(std::nothrow);
-        ensure_done(coro);
+        LLCoros::instance().launch("test<15>", boost::bind(&coroutine_data::postAndWait2_1, this));
         ensure_equals(result.asInteger(), 19);
         ensure_equals(which, 1);
     }
@@ -721,9 +687,7 @@ namespace tut
     {
         set_test_name("coroPumpPost");
         DEBUG;
-        coroutine_type coro(boost::bind(&coroutine_data::coroPumpPost, this, _1));
-        coro(std::nothrow);
-        ensure_done(coro);
+        LLCoros::instance().launch("test<16>", boost::bind(&coroutine_data::coroPumpPost, this));
         ensure_equals(result.asInteger(), 18);
     }
 
@@ -732,9 +696,7 @@ namespace tut
     {
         set_test_name("coroPumpsPost reply");
         DEBUG;
-        coroutine_type coro(boost::bind(&coroutine_data::coroPumpsPost, this, _1));
-        coro(std::nothrow);
-        ensure_done(coro);
+        LLCoros::instance().launch("test<17>", boost::bind(&coroutine_data::coroPumpsPost, this));
         ensure_equals(result.asInteger(), 24);
         ensure_equals("which pump", which, 0);
     }
@@ -744,9 +706,7 @@ namespace tut
     {
         set_test_name("coroPumpsPost error");
         DEBUG;
-        coroutine_type coro(boost::bind(&coroutine_data::coroPumpsPost_1, this, _1));
-        coro(std::nothrow);
-        ensure_done(coro);
+        LLCoros::instance().launch("test<18>", boost::bind(&coroutine_data::coroPumpsPost_1, this));
         ensure_equals(result.asInteger(), 24);
         ensure_equals("which pump", which, 1);
     }
@@ -756,9 +716,8 @@ namespace tut
     {
         set_test_name("coroPumpsPostNoEx");
         DEBUG;
-        coroutine_type coro(boost::bind(&coroutine_data::coroPumpsPostNoEx, this, _1));
-        coro(std::nothrow);
-        ensure_done(coro);
+        LLCoros::instance().launch("test<19>",
+                                   boost::bind(&coroutine_data::coroPumpsPostNoEx, this));
         ensure_equals(result.asInteger(), 9);
     }
 
@@ -767,9 +726,7 @@ namespace tut
     {
         set_test_name("coroPumpsPostEx");
         DEBUG;
-        coroutine_type coro(boost::bind(&coroutine_data::coroPumpsPostEx, this, _1));
-        coro(std::nothrow);
-        ensure_done(coro);
+        LLCoros::instance().launch("test<20>", boost::bind(&coroutine_data::coroPumpsPostEx, this));
         ensure("no result", result.isUndefined());
         ensure_equals("got error", errordata.asInteger(), 10);
     }
@@ -779,9 +736,8 @@ namespace tut
     {
         set_test_name("coroPumpsPostNoLog");
         DEBUG;
-        coroutine_type coro(boost::bind(&coroutine_data::coroPumpsPostNoLog, this, _1));
-        coro(std::nothrow);
-        ensure_done(coro);
+        LLCoros::instance().launch("test<21>",
+                                   boost::bind(&coroutine_data::coroPumpsPostNoLog, this));
         ensure_equals(result.asInteger(), 31);
     }
 
@@ -790,9 +746,7 @@ namespace tut
     {
         set_test_name("coroPumpsPostLog");
         DEBUG;
-        coroutine_type coro(boost::bind(&coroutine_data::coroPumpsPostLog, this, _1));
-        coro(std::nothrow);
-        ensure_done(coro);
+        LLCoros::instance().launch("test<22>", boost::bind(&coroutine_data::coroPumpsPostLog, this));
         ensure("no result", result.isUndefined());
         ensure_contains("got error", threw, "32");
     }
-- 
cgit v1.2.3


From 7eaee4fde770edae6d64ddf07a917b2ae16a9928 Mon Sep 17 00:00:00 2001
From: Nat Goodspeed <nat@lindenlab.com>
Date: Wed, 1 Jul 2015 19:14:24 -0400
Subject: MAINT-5351: Reorganize lleventcoro_test.cpp to be more readable. Each
 test<n>() method invokes a function from earlier in the source. It's much
 better if each of those functions immediately precedes the test that invokes
 it.

---
 indra/llcommon/tests/lleventcoro_test.cpp | 660 ++++++++++++++++--------------
 1 file changed, 344 insertions(+), 316 deletions(-)

(limited to 'indra/llcommon/tests')

diff --git a/indra/llcommon/tests/lleventcoro_test.cpp b/indra/llcommon/tests/lleventcoro_test.cpp
index 31e9856477..da927038ab 100755
--- a/indra/llcommon/tests/lleventcoro_test.cpp
+++ b/indra/llcommon/tests/lleventcoro_test.cpp
@@ -160,298 +160,7 @@ private:
 *****************************************************************************/
 namespace tut
 {
-    struct coroutine_data
-    {
-        // Define coroutine bodies as methods here so they can use ensure*()
-
-        void explicit_wait(boost::dcoroutines::coroutine<void()>::self& self)
-        {
-            BEGIN
-            {
-                // ... do whatever preliminary stuff must happen ...
-
-                // declare the future
-                boost::dcoroutines::future<LLSD> future(self);
-                // tell the future what to wait for
-                LLTempBoundListener connection(
-                    LLEventPumps::instance().obtain("source").listen("coro", voidlistener(boost::dcoroutines::make_callback(future))));
-                ensure("Not yet", ! future);
-                // attempting to dereference ("resolve") the future causes the calling
-                // coroutine to wait for it
-                debug("about to wait");
-                result = *future;
-                ensure("Got it", future);
-            }
-            END
-        }
-
-        void waitForEventOn1()
-        {
-            BEGIN
-            {
-                result = waitForEventOn("source");
-            }
-            END
-        }
-
-        void waitForEventOn2()
-        {
-            BEGIN
-            {
-                LLEventWithID pair = waitForEventOn("reply", "error");
-                result = pair.first;
-                which  = pair.second;
-                debug(STRINGIZE("result = " << result << ", which = " << which));
-            }
-            END
-        }
-
-        void postAndWait1()
-        {
-            BEGIN
-            {
-                result = postAndWait(LLSDMap("value", 17),       // request event
-                                     immediateAPI.getPump(),     // requestPump
-                                     "reply1",                   // replyPump
-                                     "reply");                   // request["reply"] = name
-            }
-            END
-        }
-
-        void postAndWait2()
-        {
-            BEGIN
-            {
-                LLEventWithID pair = ::postAndWait2(LLSDMap("value", 18),
-                                                    immediateAPI.getPump(),
-                                                    "reply2",
-                                                    "error2",
-                                                    "reply",
-                                                    "error");
-                result = pair.first;
-                which  = pair.second;
-                debug(STRINGIZE("result = " << result << ", which = " << which));
-            }
-            END
-        }
-
-        void postAndWait2_1()
-        {
-            BEGIN
-            {
-                LLEventWithID pair = ::postAndWait2(LLSDMap("value", 18)("fail", LLSD()),
-                                                    immediateAPI.getPump(),
-                                                    "reply2",
-                                                    "error2",
-                                                    "reply",
-                                                    "error");
-                result = pair.first;
-                which  = pair.second;
-                debug(STRINGIZE("result = " << result << ", which = " << which));
-            }
-            END
-        }
-
-        void coroPump()
-        {
-            BEGIN
-            {
-                LLCoroEventPump waiter;
-                replyName = waiter.getName();
-                result = waiter.wait();
-            }
-            END
-        }
-
-        void coroPumpPost()
-        {
-            BEGIN
-            {
-                LLCoroEventPump waiter;
-                result = waiter.postAndWait(LLSDMap("value", 17),
-                                            immediateAPI.getPump(), "reply");
-            }
-            END
-        }
-
-        void coroPumps()
-        {
-            BEGIN
-            {
-                LLCoroEventPumps waiter;
-                replyName = waiter.getName0();
-                errorName = waiter.getName1();
-                LLEventWithID pair(waiter.wait());
-                result = pair.first;
-                which  = pair.second;
-            }
-            END
-        }
-
-        void coroPumpsNoEx()
-        {
-            BEGIN
-            {
-                LLCoroEventPumps waiter;
-                replyName = waiter.getName0();
-                errorName = waiter.getName1();
-                result = waiter.waitWithException();
-            }
-            END
-        }
-
-        void coroPumpsEx()
-        {
-            BEGIN
-            {
-                LLCoroEventPumps waiter;
-                replyName = waiter.getName0();
-                errorName = waiter.getName1();
-                try
-                {
-                    result = waiter.waitWithException();
-                    debug("no exception");
-                }
-                catch (const LLErrorEvent& e)
-                {
-                    debug(STRINGIZE("exception " << e.what()));
-                    errordata = e.getData();
-                }
-            }
-            END
-        }
-
-        void coroPumpsNoLog()
-        {
-            BEGIN
-            {
-                LLCoroEventPumps waiter;
-                replyName = waiter.getName0();
-                errorName = waiter.getName1();
-                result = waiter.waitWithLog();
-            }
-            END
-        }
-
-        void coroPumpsLog()
-        {
-            BEGIN
-            {
-                LLCoroEventPumps waiter;
-                replyName = waiter.getName0();
-                errorName = waiter.getName1();
-                WrapLLErrs capture;
-                try
-                {
-                    result = waiter.waitWithLog();
-                    debug("no exception");
-                }
-                catch (const WrapLLErrs::FatalException& e)
-                {
-                    debug(STRINGIZE("exception " << e.what()));
-                    threw = e.what();
-                }
-            }
-            END
-        }
-
-        void coroPumpsPost()
-        {
-            BEGIN
-            {
-                LLCoroEventPumps waiter;
-                LLEventWithID pair(waiter.postAndWait(LLSDMap("value", 23),
-                                                      immediateAPI.getPump(), "reply", "error"));
-                result = pair.first;
-                which  = pair.second;
-            }
-            END
-        }
-
-        void coroPumpsPost_1()
-        {
-            BEGIN
-            {
-                LLCoroEventPumps waiter;
-                LLEventWithID pair(
-                    waiter.postAndWait(LLSDMap("value", 23)("fail", LLSD()),
-                                       immediateAPI.getPump(), "reply", "error"));
-                result = pair.first;
-                which  = pair.second;
-            }
-            END
-        }
-
-        void coroPumpsPostNoEx()
-        {
-            BEGIN
-            {
-                LLCoroEventPumps waiter;
-                result = waiter.postAndWaitWithException(LLSDMap("value", 8),
-                                                         immediateAPI.getPump(), "reply", "error");
-            }
-            END
-        }
-
-        void coroPumpsPostEx()
-        {
-            BEGIN
-            {
-                LLCoroEventPumps waiter;
-                try
-                {
-                    result = waiter.postAndWaitWithException(
-                        LLSDMap("value", 9)("fail", LLSD()),
-                        immediateAPI.getPump(), "reply", "error");
-                    debug("no exception");
-                }
-                catch (const LLErrorEvent& e)
-                {
-                    debug(STRINGIZE("exception " << e.what()));
-                    errordata = e.getData();
-                }
-            }
-            END
-        }
-
-        void coroPumpsPostNoLog()
-        {
-            BEGIN
-            {
-                LLCoroEventPumps waiter;
-                result = waiter.postAndWaitWithLog(LLSDMap("value", 30),
-                                                   immediateAPI.getPump(), "reply", "error");
-            }
-            END
-        }
-
-        void coroPumpsPostLog()
-        {
-            BEGIN
-            {
-                LLCoroEventPumps waiter;
-                WrapLLErrs capture;
-                try
-                {
-                    result = waiter.postAndWaitWithLog(
-                        LLSDMap("value", 31)("fail", LLSD()),
-                        immediateAPI.getPump(), "reply", "error");
-                    debug("no exception");
-                }
-                catch (const WrapLLErrs::FatalException& e)
-                {
-                    debug(STRINGIZE("exception " << e.what()));
-                    threw = e.what();
-                }
-            }
-            END
-        }
-
-        ImmediateAPI immediateAPI;
-        std::string replyName, errorName, threw;
-        LLSD result, errordata;
-        int which;
-    };
+    struct coroutine_data {};
     typedef test_group<coroutine_data> coroutine_group;
     typedef coroutine_group::object object;
     coroutine_group coroutinegrp("coroutine");
@@ -501,9 +210,49 @@ namespace tut
         ensure("done", ! matcher);
     }
 
+    // use static data so we can intersperse coroutine functions with the
+    // tests that engage them
+    ImmediateAPI immediateAPI;
+    std::string replyName, errorName, threw;
+    LLSD result, errordata;
+    int which;
+
+    // reinit vars at the start of each test
+    void clear()
+    {
+        replyName.clear();
+        errorName.clear();
+        threw.clear();
+        result = LLSD();
+        errordata = LLSD();
+        which = 0;
+    }
+
+    void explicit_wait(boost::dcoroutines::coroutine<void()>::self& self)
+    {
+        BEGIN
+        {
+            // ... do whatever preliminary stuff must happen ...
+
+            // declare the future
+            boost::dcoroutines::future<LLSD> future(self);
+            // tell the future what to wait for
+            LLTempBoundListener connection(
+                LLEventPumps::instance().obtain("source").listen("coro", voidlistener(boost::dcoroutines::make_callback(future))));
+            ensure("Not yet", ! future);
+            // attempting to dereference ("resolve") the future causes the calling
+            // coroutine to wait for it
+            debug("about to wait");
+            result = *future;
+            ensure("Got it", future);
+        }
+        END
+    }
+
     template<> template<>
     void object::test<2>()
     {
+        clear();
         set_test_name("explicit_wait");
         DEBUG;
 
@@ -511,7 +260,7 @@ namespace tut
         // Pass the ctor a callable that accepts the coroutine_type::self
         // param passed by the library.
         boost::dcoroutines::coroutine<void()>
-        coro(boost::bind(&coroutine_data::explicit_wait, this, _1));
+        coro(explicit_wait);
         // Start the coroutine
         coro(std::nothrow);
         // When the coroutine waits for the event pump, it returns here.
@@ -524,26 +273,48 @@ namespace tut
         ensure_equals(result.asString(), "received");
     }
 
+    void waitForEventOn1()
+    {
+        BEGIN
+        {
+            result = waitForEventOn("source");
+        }
+        END
+    }
+
     template<> template<>
     void object::test<3>()
     {
+        clear();
         set_test_name("waitForEventOn1");
         DEBUG;
-        LLCoros::instance().launch("test<3>",
-                                   boost::bind(&coroutine_data::waitForEventOn1, this));
+        LLCoros::instance().launch("test<3>", waitForEventOn1);
         debug("about to send");
         LLEventPumps::instance().obtain("source").post("received");
         debug("back from send");
         ensure_equals(result.asString(), "received");
     }
 
+    void waitForEventOn2()
+    {
+        BEGIN
+        {
+            LLEventWithID pair = waitForEventOn("reply", "error");
+            result = pair.first;
+            which  = pair.second;
+            debug(STRINGIZE("result = " << result << ", which = " << which));
+        }
+        END
+    }
+
     template<> template<>
     void object::test<4>()
     {
+        clear();
         set_test_name("waitForEventOn2 reply");
         {
         DEBUG;
-        LLCoros::instance().launch("test<4>", boost::bind(&coroutine_data::waitForEventOn2, this));
+        LLCoros::instance().launch("test<4>", waitForEventOn2);
         debug("about to send");
         LLEventPumps::instance().obtain("reply").post("received");
         debug("back from send");
@@ -555,9 +326,10 @@ namespace tut
     template<> template<>
     void object::test<5>()
     {
+        clear();
         set_test_name("waitForEventOn2 error");
         DEBUG;
-        LLCoros::instance().launch("test<5>", boost::bind(&coroutine_data::waitForEventOn2, this));
+        LLCoros::instance().launch("test<5>", waitForEventOn2);
         debug("about to send");
         LLEventPumps::instance().obtain("error").post("badness");
         debug("back from send");
@@ -565,24 +337,51 @@ namespace tut
         ensure_equals("which pump", which, 1);
     }
 
+    void coroPump()
+    {
+        BEGIN
+        {
+            LLCoroEventPump waiter;
+            replyName = waiter.getName();
+            result = waiter.wait();
+        }
+        END
+    }
+
     template<> template<>
     void object::test<6>()
     {
+        clear();
         set_test_name("coroPump");
         DEBUG;
-        LLCoros::instance().launch("test<6>", boost::bind(&coroutine_data::coroPump, this));
+        LLCoros::instance().launch("test<6>", coroPump);
         debug("about to send");
         LLEventPumps::instance().obtain(replyName).post("received");
         debug("back from send");
         ensure_equals(result.asString(), "received");
     }
 
+    void coroPumps()
+    {
+        BEGIN
+        {
+            LLCoroEventPumps waiter;
+            replyName = waiter.getName0();
+            errorName = waiter.getName1();
+            LLEventWithID pair(waiter.wait());
+            result = pair.first;
+            which  = pair.second;
+        }
+        END
+    }
+
     template<> template<>
     void object::test<7>()
     {
+        clear();
         set_test_name("coroPumps reply");
         DEBUG;
-        LLCoros::instance().launch("test<7>", boost::bind(&coroutine_data::coroPumps, this));
+        LLCoros::instance().launch("test<7>", coroPumps);
         debug("about to send");
         LLEventPumps::instance().obtain(replyName).post("received");
         debug("back from send");
@@ -593,9 +392,10 @@ namespace tut
     template<> template<>
     void object::test<8>()
     {
+        clear();
         set_test_name("coroPumps error");
         DEBUG;
-        LLCoros::instance().launch("test<8>", boost::bind(&coroutine_data::coroPumps, this));
+        LLCoros::instance().launch("test<8>", coroPumps);
         debug("about to send");
         LLEventPumps::instance().obtain(errorName).post("badness");
         debug("back from send");
@@ -603,24 +403,59 @@ namespace tut
         ensure_equals("which pump", which, 1);
     }
 
+    void coroPumpsNoEx()
+    {
+        BEGIN
+        {
+            LLCoroEventPumps waiter;
+            replyName = waiter.getName0();
+            errorName = waiter.getName1();
+            result = waiter.waitWithException();
+        }
+        END
+    }
+
     template<> template<>
     void object::test<9>()
     {
+        clear();
         set_test_name("coroPumpsNoEx");
         DEBUG;
-        LLCoros::instance().launch("test<9>", boost::bind(&coroutine_data::coroPumpsNoEx, this));
+        LLCoros::instance().launch("test<9>", coroPumpsNoEx);
         debug("about to send");
         LLEventPumps::instance().obtain(replyName).post("received");
         debug("back from send");
         ensure_equals(result.asString(), "received");
     }
 
+    void coroPumpsEx()
+    {
+        BEGIN
+        {
+            LLCoroEventPumps waiter;
+            replyName = waiter.getName0();
+            errorName = waiter.getName1();
+            try
+            {
+                result = waiter.waitWithException();
+                debug("no exception");
+            }
+            catch (const LLErrorEvent& e)
+            {
+                debug(STRINGIZE("exception " << e.what()));
+                errordata = e.getData();
+            }
+        }
+        END
+    }
+
     template<> template<>
     void object::test<10>()
     {
+        clear();
         set_test_name("coroPumpsEx");
         DEBUG;
-        LLCoros::instance().launch("test<10>", boost::bind(&coroutine_data::coroPumpsEx, this));
+        LLCoros::instance().launch("test<10>", coroPumpsEx);
         debug("about to send");
         LLEventPumps::instance().obtain(errorName).post("badness");
         debug("back from send");
@@ -628,24 +463,60 @@ namespace tut
         ensure_equals("got error", errordata.asString(), "badness");
     }
 
+    void coroPumpsNoLog()
+    {
+        BEGIN
+        {
+            LLCoroEventPumps waiter;
+            replyName = waiter.getName0();
+            errorName = waiter.getName1();
+            result = waiter.waitWithLog();
+        }
+        END
+    }
+
     template<> template<>
     void object::test<11>()
     {
+        clear();
         set_test_name("coroPumpsNoLog");
         DEBUG;
-        LLCoros::instance().launch("test<11>", boost::bind(&coroutine_data::coroPumpsNoLog, this));
+        LLCoros::instance().launch("test<11>", coroPumpsNoLog);
         debug("about to send");
         LLEventPumps::instance().obtain(replyName).post("received");
         debug("back from send");
         ensure_equals(result.asString(), "received");
     }
 
+    void coroPumpsLog()
+    {
+        BEGIN
+        {
+            LLCoroEventPumps waiter;
+            replyName = waiter.getName0();
+            errorName = waiter.getName1();
+            WrapLLErrs capture;
+            try
+            {
+                result = waiter.waitWithLog();
+                debug("no exception");
+            }
+            catch (const WrapLLErrs::FatalException& e)
+            {
+                debug(STRINGIZE("exception " << e.what()));
+                threw = e.what();
+            }
+        }
+        END
+    }
+
     template<> template<>
     void object::test<12>()
     {
+        clear();
         set_test_name("coroPumpsLog");
         DEBUG;
-        LLCoros::instance().launch("test<12>", boost::bind(&coroutine_data::coroPumpsLog, this));
+        LLCoros::instance().launch("test<12>", coroPumpsLog);
         debug("about to send");
         LLEventPumps::instance().obtain(errorName).post("badness");
         debug("back from send");
@@ -653,100 +524,257 @@ namespace tut
         ensure_contains("got error", threw, "badness");
     }
 
+    void postAndWait1()
+    {
+        BEGIN
+        {
+            result = postAndWait(LLSDMap("value", 17),       // request event
+                                 immediateAPI.getPump(),     // requestPump
+                                 "reply1",                   // replyPump
+                                 "reply");                   // request["reply"] = name
+        }
+        END
+    }
+
     template<> template<>
     void object::test<13>()
     {
+        clear();
         set_test_name("postAndWait1");
         DEBUG;
-        LLCoros::instance().launch("test<13>", boost::bind(&coroutine_data::postAndWait1, this));
+        LLCoros::instance().launch("test<13>", postAndWait1);
         ensure_equals(result.asInteger(), 18);
     }
 
+    void postAndWait2()
+    {
+        BEGIN
+        {
+            LLEventWithID pair = ::postAndWait2(LLSDMap("value", 18),
+                                                immediateAPI.getPump(),
+                                                "reply2",
+                                                "error2",
+                                                "reply",
+                                                "error");
+            result = pair.first;
+            which  = pair.second;
+            debug(STRINGIZE("result = " << result << ", which = " << which));
+        }
+        END
+    }
+
     template<> template<>
     void object::test<14>()
     {
+        clear();
         set_test_name("postAndWait2");
         DEBUG;
-        LLCoros::instance().launch("test<14>", boost::bind(&coroutine_data::postAndWait2, this));
+        LLCoros::instance().launch("test<14>", postAndWait2);
         ensure_equals(result.asInteger(), 19);
         ensure_equals(which, 0);
     }
 
+    void postAndWait2_1()
+    {
+        BEGIN
+        {
+            LLEventWithID pair = ::postAndWait2(LLSDMap("value", 18)("fail", LLSD()),
+                                                immediateAPI.getPump(),
+                                                "reply2",
+                                                "error2",
+                                                "reply",
+                                                "error");
+            result = pair.first;
+            which  = pair.second;
+            debug(STRINGIZE("result = " << result << ", which = " << which));
+        }
+        END
+    }
+
     template<> template<>
     void object::test<15>()
     {
+        clear();
         set_test_name("postAndWait2_1");
         DEBUG;
-        LLCoros::instance().launch("test<15>", boost::bind(&coroutine_data::postAndWait2_1, this));
+        LLCoros::instance().launch("test<15>", postAndWait2_1);
         ensure_equals(result.asInteger(), 19);
         ensure_equals(which, 1);
     }
 
+    void coroPumpPost()
+    {
+        BEGIN
+        {
+            LLCoroEventPump waiter;
+            result = waiter.postAndWait(LLSDMap("value", 17),
+                                        immediateAPI.getPump(), "reply");
+        }
+        END
+    }
+
     template<> template<>
     void object::test<16>()
     {
+        clear();
         set_test_name("coroPumpPost");
         DEBUG;
-        LLCoros::instance().launch("test<16>", boost::bind(&coroutine_data::coroPumpPost, this));
+        LLCoros::instance().launch("test<16>", coroPumpPost);
         ensure_equals(result.asInteger(), 18);
     }
 
+    void coroPumpsPost()
+    {
+        BEGIN
+        {
+            LLCoroEventPumps waiter;
+            LLEventWithID pair(waiter.postAndWait(LLSDMap("value", 23),
+                                                  immediateAPI.getPump(), "reply", "error"));
+            result = pair.first;
+            which  = pair.second;
+        }
+        END
+    }
+
     template<> template<>
     void object::test<17>()
     {
+        clear();
         set_test_name("coroPumpsPost reply");
         DEBUG;
-        LLCoros::instance().launch("test<17>", boost::bind(&coroutine_data::coroPumpsPost, this));
+        LLCoros::instance().launch("test<17>", coroPumpsPost);
         ensure_equals(result.asInteger(), 24);
         ensure_equals("which pump", which, 0);
     }
 
+    void coroPumpsPost_1()
+    {
+        BEGIN
+        {
+            LLCoroEventPumps waiter;
+            LLEventWithID pair(
+                waiter.postAndWait(LLSDMap("value", 23)("fail", LLSD()),
+                                   immediateAPI.getPump(), "reply", "error"));
+            result = pair.first;
+            which  = pair.second;
+        }
+        END
+    }
+
     template<> template<>
     void object::test<18>()
     {
+        clear();
         set_test_name("coroPumpsPost error");
         DEBUG;
-        LLCoros::instance().launch("test<18>", boost::bind(&coroutine_data::coroPumpsPost_1, this));
+        LLCoros::instance().launch("test<18>", coroPumpsPost_1);
         ensure_equals(result.asInteger(), 24);
         ensure_equals("which pump", which, 1);
     }
 
+    void coroPumpsPostNoEx()
+    {
+        BEGIN
+        {
+            LLCoroEventPumps waiter;
+            result = waiter.postAndWaitWithException(LLSDMap("value", 8),
+                                                     immediateAPI.getPump(), "reply", "error");
+        }
+        END
+    }
+
     template<> template<>
     void object::test<19>()
     {
+        clear();
         set_test_name("coroPumpsPostNoEx");
         DEBUG;
-        LLCoros::instance().launch("test<19>",
-                                   boost::bind(&coroutine_data::coroPumpsPostNoEx, this));
+        LLCoros::instance().launch("test<19>", coroPumpsPostNoEx);
         ensure_equals(result.asInteger(), 9);
     }
 
+    void coroPumpsPostEx()
+    {
+        BEGIN
+        {
+            LLCoroEventPumps waiter;
+            try
+            {
+                result = waiter.postAndWaitWithException(
+                    LLSDMap("value", 9)("fail", LLSD()),
+                    immediateAPI.getPump(), "reply", "error");
+                debug("no exception");
+            }
+            catch (const LLErrorEvent& e)
+            {
+                debug(STRINGIZE("exception " << e.what()));
+                errordata = e.getData();
+            }
+        }
+        END
+    }
+
     template<> template<>
     void object::test<20>()
     {
+        clear();
         set_test_name("coroPumpsPostEx");
         DEBUG;
-        LLCoros::instance().launch("test<20>", boost::bind(&coroutine_data::coroPumpsPostEx, this));
+        LLCoros::instance().launch("test<20>", coroPumpsPostEx);
         ensure("no result", result.isUndefined());
         ensure_equals("got error", errordata.asInteger(), 10);
     }
 
+    void coroPumpsPostNoLog()
+    {
+        BEGIN
+        {
+            LLCoroEventPumps waiter;
+            result = waiter.postAndWaitWithLog(LLSDMap("value", 30),
+                                               immediateAPI.getPump(), "reply", "error");
+        }
+        END
+    }
+
     template<> template<>
     void object::test<21>()
     {
+        clear();
         set_test_name("coroPumpsPostNoLog");
         DEBUG;
-        LLCoros::instance().launch("test<21>",
-                                   boost::bind(&coroutine_data::coroPumpsPostNoLog, this));
+        LLCoros::instance().launch("test<21>", coroPumpsPostNoLog);
         ensure_equals(result.asInteger(), 31);
     }
 
+    void coroPumpsPostLog()
+    {
+        BEGIN
+        {
+            LLCoroEventPumps waiter;
+            WrapLLErrs capture;
+            try
+            {
+                result = waiter.postAndWaitWithLog(
+                    LLSDMap("value", 31)("fail", LLSD()),
+                    immediateAPI.getPump(), "reply", "error");
+                debug("no exception");
+            }
+            catch (const WrapLLErrs::FatalException& e)
+            {
+                debug(STRINGIZE("exception " << e.what()));
+                threw = e.what();
+            }
+        }
+        END
+    }
+
     template<> template<>
     void object::test<22>()
     {
+        clear();
         set_test_name("coroPumpsPostLog");
         DEBUG;
-        LLCoros::instance().launch("test<22>", boost::bind(&coroutine_data::coroPumpsPostLog, this));
+        LLCoros::instance().launch("test<22>", coroPumpsPostLog);
         ensure("no result", result.isUndefined());
         ensure_contains("got error", threw, "32");
     }
-- 
cgit v1.2.3