Moving Wait() to XObject base.

This commit is contained in:
Ben Vanik 2014-01-05 01:22:08 -08:00
parent 8bba532f25
commit 372fd97821
12 changed files with 56 additions and 135 deletions

View File

@ -63,39 +63,3 @@ int32_t XEvent::Reset() {
void XEvent::Clear() {
ResetEvent(handle_);
}
X_STATUS XEvent::Wait(uint32_t wait_reason, uint32_t processor_mode,
uint32_t alertable, uint64_t* opt_timeout) {
DWORD timeout_ms;
if (opt_timeout) {
int64_t timeout_ticks = (int64_t)(*opt_timeout);
if (timeout_ticks > 0) {
// Absolute time, based on January 1, 1601.
// TODO(benvanik): convert time to relative time.
XEASSERTALWAYS();
timeout_ms = 0;
} else if (timeout_ticks < 0) {
// Relative time.
timeout_ms = (DWORD)(-timeout_ticks / 10000); // Ticks -> MS
} else {
timeout_ms = 0;
}
} else {
timeout_ms = INFINITE;
}
DWORD result = WaitForSingleObjectEx(handle_, timeout_ms, alertable);
switch (result) {
case WAIT_OBJECT_0:
return X_STATUS_SUCCESS;
case WAIT_IO_COMPLETION:
// Or X_STATUS_ALERTED?
return X_STATUS_USER_APC;
case WAIT_TIMEOUT:
return X_STATUS_TIMEOUT;
default:
case WAIT_FAILED:
case WAIT_ABANDONED:
return X_STATUS_ABANDONED_WAIT_0;
}
}

View File

@ -31,8 +31,7 @@ public:
int32_t Reset();
void Clear();
virtual X_STATUS Wait(uint32_t wait_reason, uint32_t processor_mode,
uint32_t alertable, uint64_t* opt_timeout);
virtual void* GetWaitHandle() { return handle_; }
private:
HANDLE handle_;

View File

@ -30,11 +30,8 @@ XFile::~XFile() {
async_event_->Delete();
}
X_STATUS XFile::Wait(uint32_t wait_reason, uint32_t processor_mode,
uint32_t alertable, uint64_t* opt_timeout) {
// Wait until some async operation completes.
return async_event_->Wait(
wait_reason, processor_mode, alertable, opt_timeout);
void* XFile::GetWaitHandle() {
return async_event_->GetWaitHandle();
}
X_STATUS XFile::Read(void* buffer, size_t buffer_length, size_t byte_offset,

View File

@ -52,9 +52,6 @@ public:
size_t position() const { return position_; }
void set_position(size_t value) { position_ = value; }
virtual X_STATUS Wait(uint32_t wait_reason, uint32_t processor_mode,
uint32_t alertable, uint64_t* opt_timeout);
virtual X_STATUS QueryInfo(XFileInfo* out_info) = 0;
X_STATUS Read(void* buffer, size_t buffer_length, size_t byte_offset,
@ -62,6 +59,8 @@ public:
X_STATUS Read(void* buffer, size_t buffer_length, size_t byte_offset,
XAsyncRequest* request);
virtual void* GetWaitHandle();
protected:
XFile(KernelState* kernel_state, uint32_t desired_access);
virtual X_STATUS ReadSync(

View File

@ -86,40 +86,3 @@ bool XNotifyListener::DequeueNotification(
xe_mutex_unlock(lock_);
return dequeued;
}
// TODO(benvanik): move this to common class
X_STATUS XNotifyListener::Wait(uint32_t wait_reason, uint32_t processor_mode,
uint32_t alertable, uint64_t* opt_timeout) {
DWORD timeout_ms;
if (opt_timeout) {
int64_t timeout_ticks = (int64_t)(*opt_timeout);
if (timeout_ticks > 0) {
// Absolute time, based on January 1, 1601.
// TODO(benvanik): convert time to relative time.
XEASSERTALWAYS();
timeout_ms = 0;
} else if (timeout_ticks < 0) {
// Relative time.
timeout_ms = (DWORD)(-timeout_ticks / 10000); // Ticks -> MS
} else {
timeout_ms = 0;
}
} else {
timeout_ms = INFINITE;
}
DWORD result = WaitForSingleObjectEx(wait_handle_, timeout_ms, alertable);
switch (result) {
case WAIT_OBJECT_0:
return X_STATUS_SUCCESS;
case WAIT_IO_COMPLETION:
// Or X_STATUS_ALERTED?
return X_STATUS_USER_APC;
case WAIT_TIMEOUT:
return X_STATUS_TIMEOUT;
default:
case WAIT_FAILED:
case WAIT_ABANDONED:
return X_STATUS_ABANDONED_WAIT_0;
}
}

View File

@ -36,8 +36,7 @@ public:
bool DequeueNotification(XNotificationID* out_id, uint32_t* out_data);
bool DequeueNotification(XNotificationID id, uint32_t* out_data);
virtual X_STATUS Wait(uint32_t wait_reason, uint32_t processor_mode,
uint32_t alertable, uint64_t* opt_timeout);
virtual void* GetWaitHandle() { return wait_handle_; }
private:
HANDLE wait_handle_;

View File

@ -43,40 +43,3 @@ int32_t XSemaphore::ReleaseSemaphore(int32_t release_count) {
::ReleaseSemaphore(handle_, release_count, &previous_count);
return previous_count;
}
X_STATUS XSemaphore::Wait(
uint32_t wait_reason, uint32_t processor_mode,
uint32_t alertable, uint64_t* opt_timeout) {
DWORD timeout_ms;
if (opt_timeout) {
int64_t timeout_ticks = (int64_t)(*opt_timeout);
if (timeout_ticks > 0) {
// Absolute time, based on January 1, 1601.
// TODO(benvanik): convert time to relative time.
XEASSERTALWAYS();
timeout_ms = 0;
} else if (timeout_ticks < 0) {
// Relative time.
timeout_ms = (DWORD)(-timeout_ticks / 10000); // Ticks -> MS
} else {
timeout_ms = 0;
}
} else {
timeout_ms = INFINITE;
}
DWORD result = WaitForSingleObjectEx(handle_, timeout_ms, alertable);
switch (result) {
case WAIT_OBJECT_0:
return X_STATUS_SUCCESS;
case WAIT_IO_COMPLETION:
// Or X_STATUS_ALERTED?
return X_STATUS_USER_APC;
case WAIT_TIMEOUT:
return X_STATUS_TIMEOUT;
default:
case WAIT_FAILED:
case WAIT_ABANDONED:
return X_STATUS_ABANDONED_WAIT_0;
}
}

View File

@ -29,8 +29,7 @@ public:
int32_t ReleaseSemaphore(int32_t release_count);
virtual X_STATUS Wait(uint32_t wait_reason, uint32_t processor_mode,
uint32_t alertable, uint64_t* opt_timeout);
virtual void* GetWaitHandle() { return handle_; }
private:
HANDLE handle_;

View File

@ -324,11 +324,6 @@ void XThread::Execute() {
}
}
X_STATUS XThread::Wait(uint32_t wait_reason, uint32_t processor_mode,
uint32_t alertable, uint64_t* opt_timeout) {
return event_->Wait(wait_reason, processor_mode, alertable, opt_timeout);
}
void XThread::EnterCriticalRegion() {
// Global critical region. This isn't right, but is easy.
xe_mutex_lock(critical_region_);
@ -383,3 +378,7 @@ X_STATUS XThread::Delay(
return X_STATUS_ALERTED;
}
}
void* XThread::GetWaitHandle() {
return event_->GetWaitHandle();
}

View File

@ -52,9 +52,6 @@ public:
void Execute();
virtual X_STATUS Wait(uint32_t wait_reason, uint32_t processor_mode,
uint32_t alertable, uint64_t* opt_timeout);
static void EnterCriticalRegion();
static void LeaveCriticalRegion();
uint32_t RaiseIrql(uint32_t new_irql);
@ -64,6 +61,8 @@ public:
X_STATUS Delay(
uint32_t processor_mode, uint32_t alertable, uint64_t interval);
virtual void* GetWaitHandle();
private:
X_STATUS PlatformCreate();
void PlatformDestroy();

View File

@ -72,7 +72,44 @@ X_STATUS XObject::Delete() {
X_STATUS XObject::Wait(uint32_t wait_reason, uint32_t processor_mode,
uint32_t alertable, uint64_t* opt_timeout) {
return X_STATUS_SUCCESS;
void* wait_handle = GetWaitHandle();
if (!wait_handle) {
// Object doesn't support waiting.
return X_STATUS_SUCCESS;
}
DWORD timeout_ms;
if (opt_timeout) {
int64_t timeout_ticks = (int64_t)(*opt_timeout);
if (timeout_ticks > 0) {
// Absolute time, based on January 1, 1601.
// TODO(benvanik): convert time to relative time.
XEASSERTALWAYS();
timeout_ms = 0;
} else if (timeout_ticks < 0) {
// Relative time.
timeout_ms = (DWORD)(-timeout_ticks / 10000); // Ticks -> MS
} else {
timeout_ms = 0;
}
} else {
timeout_ms = INFINITE;
}
DWORD result = WaitForSingleObjectEx(wait_handle, timeout_ms, alertable);
switch (result) {
case WAIT_OBJECT_0:
return X_STATUS_SUCCESS;
case WAIT_IO_COMPLETION:
// Or X_STATUS_ALERTED?
return X_STATUS_USER_APC;
case WAIT_TIMEOUT:
return X_STATUS_TIMEOUT;
default:
case WAIT_FAILED:
case WAIT_ABANDONED:
return X_STATUS_ABANDONED_WAIT_0;
}
}
void XObject::LockType() {

View File

@ -57,14 +57,17 @@ public:
// Reference()
// Dereference()
virtual X_STATUS Wait(uint32_t wait_reason, uint32_t processor_mode,
uint32_t alertable, uint64_t* opt_timeout);
X_STATUS Wait(
uint32_t wait_reason, uint32_t processor_mode, uint32_t alertable,
uint64_t* opt_timeout);
static void LockType();
static void UnlockType();
static XObject* GetObject(KernelState* kernel_state, void* native_ptr,
int32_t as_type = -1);
virtual void* GetWaitHandle() { return 0; }
protected:
Memory* memory() const;
void SetNativePointer(uint32_t native_ptr);