XObject savestate setup (Save/Restore, tracks all handles, tracks if host object)

This commit is contained in:
Dr. Chat
2015-12-01 16:51:15 -06:00
committed by Ben Vanik
parent 1ce6a7580b
commit 5517518d36
2 changed files with 99 additions and 14 deletions

View File

@@ -11,12 +11,17 @@
#include <vector>
#include "xenia/base/byte_stream.h"
#include "xenia/base/clock.h"
#include "xenia/kernel/kernel_state.h"
#include "xenia/kernel/notify_listener.h"
#include "xenia/kernel/xboxkrnl/xboxkrnl_private.h"
#include "xenia/kernel/xenumerator.h"
#include "xenia/kernel/xevent.h"
#include "xenia/kernel/xfile.h"
#include "xenia/kernel/xmutant.h"
#include "xenia/kernel/xsemaphore.h"
#include "xenia/kernel/xthread.h"
namespace xe {
namespace kernel {
@@ -25,12 +30,11 @@ XObject::XObject(KernelState* kernel_state, Type type)
: kernel_state_(kernel_state),
pointer_ref_count_(1),
type_(type),
handle_(X_INVALID_HANDLE_VALUE),
guest_object_ptr_(0),
allocated_guest_object_(false) {
// Added pointer check to support usage without a kernel_state
if (kernel_state != nullptr) {
kernel_state->object_table()->AddHandle(this, &handle_);
handles_.reserve(10);
if (kernel_state) {
kernel_state->object_table()->AddHandle(this, &handles_[0]);
}
}
@@ -56,15 +60,13 @@ Memory* XObject::memory() const { return kernel_state_->memory(); }
XObject::Type XObject::type() { return type_; }
X_HANDLE XObject::handle() const { return handle_; }
void XObject::RetainHandle() {
kernel_state_->object_table()->RetainHandle(handle_);
kernel_state_->object_table()->RetainHandle(handles_[0]);
}
bool XObject::ReleaseHandle() {
// FIXME: Return true when handle is actually released.
return kernel_state_->object_table()->ReleaseHandle(handle_) ==
return kernel_state_->object_table()->ReleaseHandle(handles_[0]) ==
X_STATUS_SUCCESS;
}
@@ -84,10 +86,70 @@ X_STATUS XObject::Delete() {
if (!name_.empty()) {
kernel_state_->object_table()->RemoveNameMapping(name_);
}
return kernel_state_->object_table()->RemoveHandle(handle_);
return kernel_state_->object_table()->RemoveHandle(handles_[0]);
}
}
bool XObject::SaveObject(ByteStream* stream) {
stream->Write<uint32_t>(allocated_guest_object_);
stream->Write<uint32_t>(guest_object_ptr_);
stream->Write(uint32_t(handles_.size()));
stream->Write(&handles_[0], handles_.size() * sizeof(X_HANDLE));
return true;
}
bool XObject::RestoreObject(ByteStream* stream) {
allocated_guest_object_ = stream->Read<uint32_t>() > 0;
guest_object_ptr_ = stream->Read<uint32_t>();
handles_.resize(stream->Read<uint32_t>());
stream->Read(&handles_[0], handles_.size() * sizeof(X_HANDLE));
// Restore our pointer to our handles in the object table.
for (size_t i = 0; i < handles_.size(); i++) {
kernel_state_->object_table()->RestoreHandle(handles_[i], this);
}
return true;
}
object_ref<XObject> XObject::Restore(KernelState* kernel_state, Type type,
ByteStream* stream) {
switch (type) {
case kTypeEnumerator:
break;
case kTypeEvent:
return XEvent::Restore(kernel_state, stream);
case kTypeFile:
break;
case kTypeIOCompletion:
break;
case kTypeModule:
break;
case kTypeMutant:
break;
case kTypeNotifyListener:
return NotifyListener::Restore(kernel_state, stream);
case kTypeSemaphore:
break;
case kTypeSession:
break;
case kTypeSocket:
break;
case kTypeThread:
return XThread::Restore(kernel_state, stream);
case kTypeTimer:
break;
default:
assert_always("No restore handler exists for this object!");
return nullptr;
}
return nullptr;
}
void XObject::SetAttributes(uint32_t obj_attributes_ptr) {
if (!obj_attributes_ptr) {
return;
@@ -97,7 +159,7 @@ void XObject::SetAttributes(uint32_t obj_attributes_ptr) {
obj_attributes_ptr + 4);
if (!name.empty()) {
name_ = std::move(name);
kernel_state_->object_table()->AddNameMapping(name_, handle_);
kernel_state_->object_table()->AddNameMapping(name_, handles_[0]);
}
}