aboutsummaryrefslogtreecommitdiff
path: root/engines/tinsel
diff options
context:
space:
mode:
authorMax Horn2010-10-30 00:33:54 +0000
committerMax Horn2010-10-30 00:33:54 +0000
commitac94cf274290911fc3ee5395202b30f161601a62 (patch)
treefb0d699467711aefdc8a0f2de927b06ea9c16818 /engines/tinsel
parentafb5986c9eaf172d2a00530012702f7054e95521 (diff)
downloadscummvm-rg350-ac94cf274290911fc3ee5395202b30f161601a62.tar.gz
scummvm-rg350-ac94cf274290911fc3ee5395202b30f161601a62.tar.bz2
scummvm-rg350-ac94cf274290911fc3ee5395202b30f161601a62.zip
TINSEL: Fix subtle leak in coroutine code, some minor tweaks
* Fix a bug which caused coroutines invoked with nullContext to leak their state. Sadly, nullContext is underdocumented, yet very delicate and full of subtleties... ./ * Move nullContext decl from sched.cpp to coroutine.cpp * Enhance a few doxygen comments svn-id: r53934
Diffstat (limited to 'engines/tinsel')
-rw-r--r--engines/tinsel/coroutine.cpp4
-rw-r--r--engines/tinsel/coroutine.h26
-rw-r--r--engines/tinsel/sched.cpp2
3 files changed, 26 insertions, 6 deletions
diff --git a/engines/tinsel/coroutine.cpp b/engines/tinsel/coroutine.cpp
index 89d00d12ac..a1871f90b0 100644
--- a/engines/tinsel/coroutine.cpp
+++ b/engines/tinsel/coroutine.cpp
@@ -28,6 +28,10 @@
namespace Tinsel {
+
+CoroContext nullContext = NULL;
+
+
#if COROUTINE_DEBUG
namespace {
static int s_coroCount = 0;
diff --git a/engines/tinsel/coroutine.h b/engines/tinsel/coroutine.h
index 5a8084b7e3..c8b220b212 100644
--- a/engines/tinsel/coroutine.h
+++ b/engines/tinsel/coroutine.h
@@ -109,9 +109,7 @@ public:
};
-#define CORO_PARAM CoroContext &coroParam
-
-#define CORO_SUBCTX coroParam->_subctx
+#define CORO_PARAM CoroContext &coroParam
/**
@@ -159,7 +157,10 @@ public:
* @see CORO_END_CODE
*/
#define CORO_END_CODE \
- if (&coroParam == &nullContext) nullContext = NULL; \
+ if (&coroParam == &nullContext) { \
+ delete nullContext; \
+ nullContext = NULL; \
+ } \
}
/**
@@ -181,11 +182,28 @@ public:
#define CORO_KILL_SELF() \
do { if (&coroParam != &nullContext) { coroParam->_sleep = -1; } return; } while (0)
+
+/**
+ * This macro is to be used in conjunction with CORO_INVOKE_ARGS and
+ * similar macros for calling coroutines-enabled subroutines.
+ */
+#define CORO_SUBCTX coroParam->_subctx
+
/**
* Invoke another coroutine.
*
* What makes this tricky is that the coroutine we called my yield/sleep,
* and we need to deal with this adequately.
+ *
+ * @param subCoro name of the coroutine-enabled function to invoke
+ * @param ARGS list of arguments to pass to subCoro
+ *
+ * @note ARGS must be surrounded by parentheses, and the first argument
+ * in this list must always be CORO_SUBCTX. For example, the
+ * regular function call
+ * myFunc(a, b);
+ * becomes the following:
+ * CORO_INVOKE_ARGS(myFunc, (CORO_SUBCTX, a, b));
*/
#define CORO_INVOKE_ARGS(subCoro, ARGS) \
do {\
diff --git a/engines/tinsel/sched.cpp b/engines/tinsel/sched.cpp
index b1de9d4ae5..97e41e2a7d 100644
--- a/engines/tinsel/sched.cpp
+++ b/engines/tinsel/sched.cpp
@@ -45,8 +45,6 @@ struct PROCESS_STRUC {
#include "common/pack-end.h" // END STRUCT PACKING
-CoroContext nullContext = NULL;
-
//----------------- LOCAL GLOBAL DATA --------------------
static uint32 numSceneProcess;