forked from focus-creative-games/il2cpp_plus
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathThreadPoolMs.cpp
More file actions
142 lines (117 loc) · 4.85 KB
/
ThreadPoolMs.cpp
File metadata and controls
142 lines (117 loc) · 4.85 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
#include "il2cpp-api.h"
#include "il2cpp-config.h"
#include "utils/dynamic_array.h"
#include "vm/ThreadPoolMs.h"
#include "vm/Domain.h"
#include "vm/Array.h"
#include "vm/Object.h"
#include "vm/Runtime.h"
#include "os/Atomic.h"
#include "gc/WriteBarrier.h"
#include "mono/ThreadPool/threadpool-ms.h"
namespace il2cpp
{
namespace vm
{
Il2CppAsyncResult* ThreadPoolMs::DelegateBeginInvoke(Il2CppDelegate* delegate, void** params, Il2CppDelegate* asyncCallback, Il2CppObject* state)
{
#if IL2CPP_TINY
IL2CPP_ASSERT(0 && "ThreadPoolMs::DelegateBeginInvoke should not be called with the Tiny profile.");
return NULL;
#else
int numParams = delegate->method->parameters_count;
il2cpp::utils::dynamic_array<void*> newParams(numParams + 2);
for (int i = 0; i < numParams; ++i)
newParams[i] = params[i];
newParams[numParams] = asyncCallback;
newParams[numParams + 1] = state;
return threadpool_ms_begin_invoke(il2cpp::vm::Domain::GetCurrent(), (Il2CppObject*)delegate, const_cast<MethodInfo*>(delegate->method), newParams.data());
#endif
}
Il2CppObject* ThreadPoolMs::DelegateEndInvoke(Il2CppAsyncResult* asyncResult, void **out_args)
{
#if IL2CPP_TINY
IL2CPP_ASSERT(0 && "ThreadPoolMs::DelegateEndInvoke should not be called with the Tiny profile.");
return NULL;
#else
Il2CppArray *arrayOutArgs;
Il2CppObject *exc, *retVal;
retVal = threadpool_ms_end_invoke(asyncResult, &arrayOutArgs, &exc);
if (exc)
il2cpp_raise_exception((Il2CppException*)exc);
if (out_args)
{
const MethodInfo *method = asyncResult->async_delegate->method;
void** outArgsPtr = (void**)il2cpp_array_addr(arrayOutArgs, Il2CppObject*, 0);
il2cpp_array_size_t arrayOutArgsIndex = 0;
for (size_t methodParameterIndex = 0; methodParameterIndex < method->parameters_count; methodParameterIndex++)
{
const Il2CppType* paramType = method->parameters[methodParameterIndex].parameter_type;
// Assume that arrayOutArgs only contains parameters that are passed by reference.
if (!paramType->byref)
continue;
IL2CPP_ASSERT(arrayOutArgsIndex < arrayOutArgs->max_length);
Il2CppClass *paramClass = il2cpp_class_from_type(paramType);
if (paramClass->valuetype)
{
IL2CPP_ASSERT(paramClass->native_size > 0 && "EndInvoke: Invalid native_size found when trying to copy a value type in the out_args.");
// NOTE(gab): in case of value types, we need to copy the data over.
memcpy(out_args[arrayOutArgsIndex], il2cpp::vm::Object::Unbox((Il2CppObject*)outArgsPtr[arrayOutArgsIndex]), paramClass->native_size);
}
else
{
*((void**)out_args[arrayOutArgsIndex]) = outArgsPtr[arrayOutArgsIndex];
}
arrayOutArgsIndex++;
}
}
return retVal;
#endif
}
Il2CppObject* ThreadPoolMs::MessageInvoke(Il2CppObject *target, Il2CppMethodMessage *msg, Il2CppObject **exc, Il2CppArray **out_args)
{
static Il2CppClass *object_array_klass = NULL;
MethodInfo *method;
Il2CppObject *ret;
Il2CppArray *arr;
int i, j, outarg_count = 0;
method = (MethodInfo*)msg->method->method;
for (i = 0; i < method->parameters_count; i++)
{
if (method->parameters[i].parameter_type->byref)
outarg_count++;
}
if (!object_array_klass)
{
Il2CppClass *klass;
klass = il2cpp_array_class_get(il2cpp_defaults.object_class, 1);
IL2CPP_ASSERT(klass);
os::Atomic::FullMemoryBarrier();
object_array_klass = klass;
}
arr = il2cpp_array_new_specific(object_array_klass, outarg_count);
il2cpp::gc::WriteBarrier::GenericStore(out_args, (Il2CppObject*)arr);
il2cpp::gc::WriteBarrier::GenericStore(exc, NULL);
ret = vm::Runtime::InvokeArray(method, method->klass->valuetype ? il2cpp_object_unbox(target) : target, method->parameters_count > 0 ? msg->args : NULL, (Il2CppException**)exc);
for (i = 0, j = 0; i < method->parameters_count; i++)
{
if (method->parameters[i].parameter_type->byref)
{
Il2CppObject* arg;
arg = (Il2CppObject*)il2cpp_array_get(msg->args, void*, i);
il2cpp_array_setref(*out_args, j, arg);
j++;
}
}
return ret;
}
void ThreadPoolMs::Suspend()
{
threadpool_ms_suspend();
}
void ThreadPoolMs::Resume()
{
threadpool_ms_resume();
}
} /* namespace vm */
} /* namespace il2cpp */