diff --git a/source/ps/LoaderThunks.h b/source/ps/LoaderThunks.h index 985b21e79a..074de90cd7 100644 --- a/source/ps/LoaderThunks.h +++ b/source/ps/LoaderThunks.h @@ -1,21 +1,30 @@ +// rationale for allocating MemFun_t dynamically: +// need to store class pointer, function, and argument for each registered +// function; single static storage isn't possible. we don't want to break +// C compat in the Loader.h interface, so we can't have it take care of this. +// that leaves dynamic alloc or reserving some static storage freed when +// load registration begins. the former is slower and requires checking +// the thunked function's return value (because we mustn't free MemFun_t +// if the function times out), but is simpler. template struct MemFun_t { T* const this_; - void(T::*func)(void); - MemFun_t(T* this__, void(T::*func_)(void)) + int(T::*func)(void); + MemFun_t(T* this__, int(T::*func_)(void)) : this_(this__), func(func_) {} }; template static int MemFunThunk(void* param, double time_left) { MemFun_t* const mf = (MemFun_t*)param; - (mf->this_->*mf->func)(); - delete mf; - return 0; + int ret = (mf->this_->*mf->func)(); + if(ret <= 0) // did not time out + delete mf; + return ret; } -template void RegMemFun(T* this_, void(T::*func)(void), +template void RegMemFun(T* this_, int(T::*func)(void), const wchar_t* description, int estimated_duration_ms) { void* param = new MemFun_t(this_, func); @@ -30,20 +39,21 @@ template struct MemFun1_t { T* const this_; Arg arg; - void(T::*func)(Arg); - MemFun1_t(T* this__, void(T::*func_)(Arg), Arg arg_) + int(T::*func)(Arg); + MemFun1_t(T* this__, int(T::*func_)(Arg), Arg arg_) : this_(this__), func(func_), arg(arg_) {} }; template static int MemFun1Thunk(void* param, double time_left) { MemFun1_t* const mf = (MemFun1_t*)param; - (mf->this_->*mf->func)(mf->arg); - delete mf; - return 0; + int ret = (mf->this_->*mf->func)(mf->arg); + if(ret <= 0) // did not time out + delete mf; + return ret; } -template void RegMemFun1(T* this_, void(T::*func)(Arg), Arg arg, +template void RegMemFun1(T* this_, int(T::*func)(Arg), Arg arg, const wchar_t* description, int estimated_duration_ms) { void* param = new MemFun1_t(this_, func, arg);