From ac94cf274290911fc3ee5395202b30f161601a62 Mon Sep 17 00:00:00 2001 From: Max Horn Date: Sat, 30 Oct 2010 00:33:54 +0000 Subject: 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 --- engines/tinsel/coroutine.cpp | 4 ++++ engines/tinsel/coroutine.h | 26 ++++++++++++++++++++++---- engines/tinsel/sched.cpp | 2 -- 3 files changed, 26 insertions(+), 6 deletions(-) (limited to 'engines/tinsel') 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; -- cgit v1.2.3