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
132 lines (107 loc) · 4.5 KB
/
ThreadPoolMs.cpp
File metadata and controls
132 lines (107 loc) · 4.5 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
#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)
{
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());
}
Il2CppObject* ThreadPoolMs::DelegateEndInvoke(Il2CppAsyncResult* asyncResult, void **out_args)
{
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];
// 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->byval_arg.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;
}
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]->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, arr);
il2cpp::gc::WriteBarrier::GenericStoreNull(exc);
ret = vm::Runtime::InvokeArray(method, method->klass->byval_arg.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]->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 */