Fixing up some overlapped completion routine stuff.

This commit is contained in:
Ben Vanik 2015-05-14 16:35:29 -07:00
parent a1fb99f1d3
commit 46eedeab01
6 changed files with 48 additions and 18 deletions

View File

@ -318,12 +318,17 @@ void KernelState::BroadcastNotification(XNotificationID id, uint32_t data) {
}
}
void KernelState::CompleteOverlapped(uint32_t overlapped_ptr, X_RESULT result,
uint32_t length) {
void KernelState::CompleteOverlapped(uint32_t overlapped_ptr, X_RESULT result) {
CompleteOverlappedEx(overlapped_ptr, result, result, 0);
}
void KernelState::CompleteOverlappedEx(uint32_t overlapped_ptr, X_RESULT result,
uint32_t extended_error,
uint32_t length) {
auto ptr = memory()->TranslateVirtual(overlapped_ptr);
XOverlappedSetResult(ptr, result);
XOverlappedSetExtendedError(ptr, extended_error);
XOverlappedSetLength(ptr, length);
XOverlappedSetExtendedError(ptr, result);
X_HANDLE event_handle = XOverlappedGetEvent(ptr);
if (event_handle) {
XEvent* ev = nullptr;
@ -347,11 +352,17 @@ void KernelState::CompleteOverlapped(uint32_t overlapped_ptr, X_RESULT result,
}
void KernelState::CompleteOverlappedImmediate(uint32_t overlapped_ptr,
X_RESULT result,
uint32_t length) {
X_RESULT result) {
CompleteOverlappedImmediateEx(overlapped_ptr, result, result, 0);
}
void KernelState::CompleteOverlappedImmediateEx(uint32_t overlapped_ptr,
X_RESULT result,
uint32_t extended_error,
uint32_t length) {
auto ptr = memory()->TranslateVirtual(overlapped_ptr);
XOverlappedSetContext(ptr, XThread::GetCurrentThreadHandle());
CompleteOverlapped(overlapped_ptr, result, length);
CompleteOverlappedEx(overlapped_ptr, result, extended_error, length);
}
} // namespace kernel

View File

@ -85,10 +85,12 @@ class KernelState {
void UnregisterNotifyListener(XNotifyListener* listener);
void BroadcastNotification(XNotificationID id, uint32_t data);
void CompleteOverlapped(uint32_t overlapped_ptr, X_RESULT result,
uint32_t length = 0);
void CompleteOverlappedImmediate(uint32_t overlapped_ptr, X_RESULT result,
uint32_t length = 0);
void CompleteOverlapped(uint32_t overlapped_ptr, X_RESULT result);
void CompleteOverlappedEx(uint32_t overlapped_ptr, X_RESULT result,
uint32_t extended_error, uint32_t length);
void CompleteOverlappedImmediate(uint32_t overlapped_ptr, X_RESULT result);
void CompleteOverlappedImmediateEx(uint32_t overlapped_ptr, X_RESULT result,
uint32_t extended_error, uint32_t length);
private:
Emulator* emulator_;

View File

@ -116,10 +116,9 @@ SHIM_CALL XamContentGetDeviceState_shim(PPCContext* ppc_state,
if ((device_id & 0xFFFF0000) != dummy_device_info_.device_id) {
if (overlapped_ptr) {
state->CompleteOverlappedImmediate(overlapped_ptr,
X_ERROR_FUNCTION_FAILED);
XOverlappedSetExtendedError(SHIM_MEM_BASE + overlapped_ptr,
X_ERROR_DEVICE_NOT_CONNECTED);
state->CompleteOverlappedImmediateEx(overlapped_ptr,
X_ERROR_FUNCTION_FAILED,
X_ERROR_DEVICE_NOT_CONNECTED, 0);
SHIM_SET_RETURN_32(X_ERROR_IO_PENDING);
} else {
SHIM_SET_RETURN_32(X_ERROR_DEVICE_NOT_CONNECTED);
@ -292,12 +291,13 @@ void XamContentCreateCore(PPCContext* ppc_state, KernelState* state,
break;
}
uint32_t disposition = create ? 1 : 2;
if (disposition_ptr) {
if (overlapped_ptr) {
// If async always set to zero, but don't set to a real value.
SHIM_SET_MEM_32(disposition_ptr, 0);
} else {
SHIM_SET_MEM_32(disposition_ptr, create ? 1 : 2);
SHIM_SET_MEM_32(disposition_ptr, disposition);
}
}
@ -308,7 +308,8 @@ void XamContentCreateCore(PPCContext* ppc_state, KernelState* state,
}
if (overlapped_ptr) {
state->CompleteOverlappedImmediate(overlapped_ptr, result);
state->CompleteOverlappedImmediateEx(overlapped_ptr, disposition, result,
0);
SHIM_SET_RETURN_32(X_ERROR_IO_PENDING);
} else {
SHIM_SET_RETURN_32(result);

View File

@ -175,7 +175,8 @@ SHIM_CALL XamEnumerate_shim(PPCContext* ppc_state, KernelState* state) {
SHIM_SET_MEM_32(item_count_ptr, item_count);
} else if (overlapped_ptr) {
assert_zero(item_count_ptr);
state->CompleteOverlappedImmediate(overlapped_ptr, result, item_count);
state->CompleteOverlappedImmediateEx(overlapped_ptr, result, result,
item_count);
result = X_ERROR_IO_PENDING;
} else {
assert_always();

View File

@ -236,7 +236,14 @@ SHIM_CALL XamUserWriteProfileSettings_shim(PPCContext* ppc_state,
user_index, unknown, setting_count, settings_ptr, overlapped_ptr);
if (!setting_count || !settings_ptr) {
SHIM_SET_RETURN_32(X_ERROR_INVALID_PARAMETER);
if (overlapped_ptr) {
state->CompleteOverlappedImmediate(overlapped_ptr,
X_ERROR_INVALID_PARAMETER);
SHIM_SET_RETURN_32(X_ERROR_IO_PENDING);
} else {
SHIM_SET_RETURN_32(X_ERROR_INVALID_PARAMETER);
}
return;
}
if (user_index == 255) {

View File

@ -212,10 +212,18 @@ enum X_FILE_INFORMATION_CLASS {
XFileMaximumInformation
};
inline uint32_t XOverlappedGetResult(void* ptr) {
auto p = reinterpret_cast<uint32_t*>(ptr);
return xe::load_and_swap<uint32_t>(&p[0]);
}
inline void XOverlappedSetResult(void* ptr, uint32_t value) {
auto p = reinterpret_cast<uint32_t*>(ptr);
xe::store_and_swap<uint32_t>(&p[0], value);
}
inline uint32_t XOverlappedGetLength(void* ptr) {
auto p = reinterpret_cast<uint32_t*>(ptr);
return xe::load_and_swap<uint32_t>(&p[1]);
}
inline void XOverlappedSetLength(void* ptr, uint32_t value) {
auto p = reinterpret_cast<uint32_t*>(ptr);
xe::store_and_swap<uint32_t>(&p[1], value);