Pyrogenesis  trunk
LoaderThunks.h
Go to the documentation of this file.
1 /* Copyright (C) 2009 Wildfire Games.
2  * This file is part of 0 A.D.
3  *
4  * 0 A.D. is free software: you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation, either version 2 of the License, or
7  * (at your option) any later version.
8  *
9  * 0 A.D. is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with 0 A.D. If not, see <http://www.gnu.org/licenses/>.
16  */
17 
18 #ifndef INCLUDED_LOADERTHUNKS
19 #define INCLUDED_LOADERTHUNKS
20 
21 // rationale for allocating MemFun_t dynamically:
22 // need to store class pointer, function, and argument for each registered
23 // function; single static storage isn't possible. we don't want to break
24 // C compat in the Loader.h interface, so we can't have it take care of this.
25 // that leaves dynamic alloc or reserving some static storage freed when
26 // load registration begins. the former is slower and requires checking
27 // the thunked function's return value (because we mustn't free MemFun_t
28 // if the function times out), but is simpler.
29 
30 // VC7 warns if T::*func is not aligned to its size (4..16 bytes on IA-32).
31 // this is a bug, since sizeof(void*) would be enough. MS says it won't
32 // be fixed: see http://www.dotnet247.com/247reference/msgs/1/7782.aspx
33 // we don't make sure alignment is acceptable because both 12 and 16 bytes
34 // may be required and padding to LCM(12,16) bytes would be wasteful;
35 // therefore, just disable the warning.
36 #if MSC_VERSION
37 #pragma warning(disable: 4121)
38 #endif
39 
40 // does this return code indicate the coroutine yielded and
41 // wasn't yet finished?
42 static inline bool ldr_was_interrupted(int ret)
43 {
44  return (0 < ret && ret <= 100);
45 }
46 
47 template<class T> struct MemFun_t
48 {
50 public:
51  T* const this_;
52  int (T::*func)(void);
53  MemFun_t(T* this__, int(T::*func_)(void))
54  : this_(this__), func(func_) {}
55 };
56 
57 template<class T> static int MemFunThunk(void* param, double UNUSED(time_left))
58 {
59  MemFun_t<T>* const mf = (MemFun_t<T>*)param;
60  int ret = (mf->this_->*mf->func)();
61 
62  if(!ldr_was_interrupted(ret))
63  delete mf;
64  return ret;
65 }
66 
67 template<class T> void RegMemFun(T* this_, int(T::*func)(void),
68  const wchar_t* description, int estimated_duration_ms)
69 {
70  void* param = new MemFun_t<T>(this_, func);
71  LDR_Register(MemFunThunk<T>, param, description, estimated_duration_ms);
72 }
73 
74 
75 ////////////////////////////////////////////////////////
76 
77 
78 template<class T, class Arg> struct MemFun1_t
79 {
81 public:
82  T* const this_;
83  Arg arg;
84  int (T::*func)(Arg);
85  MemFun1_t(T* this__, int(T::*func_)(Arg), Arg arg_)
86  : this_(this__), func(func_), arg(arg_) {}
87 };
88 
89 template<class T, class Arg> static int MemFun1Thunk(void* param, double UNUSED(time_left))
90 {
91  MemFun1_t<T, Arg>* const mf = (MemFun1_t<T, Arg>*)param;
92  int ret = (mf->this_->*mf->func)(mf->arg);
93  if(!ldr_was_interrupted(ret))
94  delete mf;
95  return ret;
96 }
97 
98 template<class T, class Arg> void RegMemFun1(T* this_, int(T::*func)(Arg), Arg arg,
99  const wchar_t* description, int estimated_duration_ms)
100 {
101  void* param = new MemFun1_t<T, Arg>(this_, func, arg);
102  LDR_Register(MemFun1Thunk<T, Arg>, param, description, estimated_duration_ms);
103 }
104 
105 #endif // INCLUDED_LOADERTHUNKS
Definition: LoaderThunks.h:78
#define UNUSED(param)
mark a function parameter as unused and avoid the corresponding compiler warning. ...
Definition: code_annotation.h:38
T *const this_
Definition: LoaderThunks.h:82
Definition: LoaderThunks.h:47
int(T::* func)(void)
Definition: LoaderThunks.h:52
Arg arg
Definition: LoaderThunks.h:83
int(T::* func)(Arg)
Definition: LoaderThunks.h:84
MemFun1_t(T *this__, int(T::*func_)(Arg), Arg arg_)
Definition: LoaderThunks.h:85
static int MemFunThunk(void *param, double time_left)
Definition: LoaderThunks.h:57
#define T(string_literal)
Definition: secure_crt.cpp:76
static int MemFun1Thunk(void *param, double time_left)
Definition: LoaderThunks.h:89
T *const this_
Definition: LoaderThunks.h:51
static bool ldr_was_interrupted(int ret)
Definition: LoaderThunks.h:42
NONCOPYABLE(MemFun_t)
MemFun_t(T *this__, int(T::*func_)(void))
Definition: LoaderThunks.h:53
void RegMemFun1(T *this_, int(T::*func)(Arg), Arg arg, const wchar_t *description, int estimated_duration_ms)
Definition: LoaderThunks.h:98
void RegMemFun(T *this_, int(T::*func)(void), const wchar_t *description, int estimated_duration_ms)
Definition: LoaderThunks.h:67
void LDR_Register(LoadFunc func, void *param, const wchar_t *description, int estimated_duration_ms)
Definition: Loader.cpp:118