ThreadEvent: Add management functions.

Currently never being triggered, though.
This commit is contained in:
Unknown W. Brackets
2016-05-28 21:17:16 -07:00
parent 04576189b4
commit e9916bdf0b
3 changed files with 99 additions and 4 deletions
+89
View File
@@ -3470,3 +3470,92 @@ int LoadExecForUser_362A956B()
Memory::Write_U32(-1, parameterArea + 8);
return 0;
}
static const SceUID SCE_TE_THREADID_ALL_USER = 0xFFFFFFF0;
enum {
THREADEVENT_CREATE = 1,
THREADEVENT_START = 2,
THREADEVENT_EXIT = 4,
THREADEVENT_DELETE = 8,
THREADEVENT_KNOWN = THREADEVENT_CREATE | THREADEVENT_START | THREADEVENT_EXIT | THREADEVENT_DELETE,
};
struct NativeThreadEventHandler {
u32 size;
char name[KERNELOBJECT_MAX_NAME_LENGTH + 1];
SceUID threadID;
u32 mask;
u32 handlerPtr;
u32 commonArg;
};
struct ThreadEventHandler : public KernelObject {
const char *GetName() { return nteh.name; }
const char *GetTypeName() { return "ThreadEventHandler"; }
static u32 GetMissingErrorCode() { return SCE_KERNEL_ERROR_UNKNOWN_TEID; }
static int GetStaticIDType() { return SCE_KERNEL_TMID_ThreadEventHandler; }
int GetIDType() const { return SCE_KERNEL_TMID_ThreadEventHandler; }
virtual void DoState(PointerWrap &p) {
auto s = p.Section("ThreadEventHandler", 1);
if (!s)
return;
p.Do(nteh);
}
NativeThreadEventHandler nteh;
};
KernelObject *__KernelThreadEventHandlerObject() {
// Default object to load from state.
return new ThreadEventHandler;
}
SceUID sceKernelRegisterThreadEventHandler(const char *name, SceUID threadID, u32 mask, u32 handlerPtr, u32 commonArg) {
if (!name) {
return hleReportError(SCEKERNEL, SCE_KERNEL_ERROR_ERROR, "invalid name");
}
if (threadID == 0) {
return hleReportError(SCEKERNEL, SCE_KERNEL_ERROR_ILLEGAL_ATTR, "invalid thread id");
}
u32 error;
if (kernelObjects.Get<Thread>(threadID, error) == NULL && threadID != SCE_TE_THREADID_ALL_USER) {
return hleReportError(SCEKERNEL, error, "bad thread id");
}
if ((mask & ~THREADEVENT_KNOWN) != 0) {
return hleReportError(SCEKERNEL, SCE_KERNEL_ERROR_ILLEGAL_MASK, "invalid event mask");
}
auto teh = new ThreadEventHandler;
teh->nteh.size = sizeof(teh->nteh);
strncpy(teh->nteh.name, name, KERNELOBJECT_MAX_NAME_LENGTH);
teh->nteh.name[KERNELOBJECT_MAX_NAME_LENGTH] = '\0';
teh->nteh.threadID = threadID;
teh->nteh.mask = mask;
teh->nteh.handlerPtr = handlerPtr;
teh->nteh.commonArg = commonArg;
SceUID uid = kernelObjects.Create(teh);
return hleLogSuccessI(SCEKERNEL, uid);
}
int sceKernelReleaseThreadEventHandler(SceUID uid) {
return hleLogSuccessI(SCEKERNEL, kernelObjects.Destroy<ThreadEventHandler>(uid));
}
int sceKernelReferThreadEventHandlerStatus(SceUID uid, u32 infoPtr) {
u32 error;
auto teh = kernelObjects.Get<ThreadEventHandler>(uid, error);
if (!teh) {
return hleReportError(SCEKERNEL, error, "bad handler id");
}
if (Memory::IsValidAddress(infoPtr) && Memory::Read_U32(infoPtr) != 0) {
Memory::WriteStruct(infoPtr, &teh->nteh);
return hleLogSuccessI(SCEKERNEL, 0);
} else {
return hleLogDebug(SCEKERNEL, 0, "struct size was 0");
}
}