XFile Save/Restore
This commit is contained in:
parent
383a173a18
commit
366f91e191
|
@ -9,7 +9,10 @@
|
|||
|
||||
#include "xenia/kernel/xfile.h"
|
||||
|
||||
#include "xenia/base/byte_stream.h"
|
||||
#include "xenia/base/logging.h"
|
||||
#include "xenia/base/math.h"
|
||||
#include "xenia/kernel/kernel_state.h"
|
||||
#include "xenia/kernel/xevent.h"
|
||||
|
||||
namespace xe {
|
||||
|
@ -17,15 +20,14 @@ namespace kernel {
|
|||
|
||||
XFile::XFile(KernelState* kernel_state, vfs::File* file)
|
||||
: XObject(kernel_state, kTypeFile), file_(file) {
|
||||
async_event_ = new XEvent(kernel_state);
|
||||
async_event_->Initialize(false, false);
|
||||
async_event_ = threading::Event::CreateAutoResetEvent(false);
|
||||
}
|
||||
|
||||
XFile::XFile() : XObject(kTypeFile) {}
|
||||
|
||||
XFile::~XFile() {
|
||||
// TODO(benvanik): signal that the file is closing?
|
||||
async_event_->Set(0, false);
|
||||
async_event_->Delete();
|
||||
|
||||
async_event_->Set();
|
||||
file_->Destroy();
|
||||
}
|
||||
|
||||
|
@ -107,7 +109,7 @@ X_STATUS XFile::Read(void* buffer, size_t buffer_length, size_t byte_offset,
|
|||
*out_bytes_read = bytes_read;
|
||||
}
|
||||
|
||||
async_event_->Set(0, false);
|
||||
async_event_->Set();
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -137,7 +139,7 @@ X_STATUS XFile::Write(const void* buffer, size_t buffer_length,
|
|||
*out_bytes_written = bytes_written;
|
||||
}
|
||||
|
||||
async_event_->Set(0, false);
|
||||
async_event_->Set();
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -160,6 +162,50 @@ void XFile::RemoveIOCompletionPort(uint32_t key) {
|
|||
}
|
||||
}
|
||||
|
||||
bool XFile::Save(ByteStream* stream) {
|
||||
XELOGD("XFile %.8X (%s)", handle(), file_->entry()->absolute_path().c_str());
|
||||
|
||||
if (!SaveObject(stream)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
stream->Write(file_->entry()->absolute_path());
|
||||
stream->Write<uint64_t>(position_);
|
||||
stream->Write(file_access());
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
object_ref<XFile> XFile::Restore(KernelState* kernel_state,
|
||||
ByteStream* stream) {
|
||||
auto file = new XFile();
|
||||
file->kernel_state_ = kernel_state;
|
||||
if (!file->RestoreObject(stream)) {
|
||||
delete file;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
auto abs_path = stream->Read<std::string>();
|
||||
uint64_t position = stream->Read<uint64_t>();
|
||||
auto access = stream->Read<uint32_t>();
|
||||
|
||||
XELOGD("XFile %.8X (%s)", file->handle(), abs_path.c_str());
|
||||
|
||||
vfs::File* vfs_file = nullptr;
|
||||
vfs::FileAction action;
|
||||
auto res = kernel_state->file_system()->OpenFile(
|
||||
abs_path, vfs::FileDisposition::kOpen, access, &vfs_file, &action);
|
||||
if (XFAILED(res)) {
|
||||
XELOGE("Failed to open XFile: error %.8X", res);
|
||||
return object_ref<XFile>(file);
|
||||
}
|
||||
|
||||
file->file_ = vfs_file;
|
||||
file->position_ = position;
|
||||
|
||||
return object_ref<XFile>(file);
|
||||
}
|
||||
|
||||
void XFile::NotifyIOCompletionPorts(
|
||||
XIOCompletion::IONotification& notification) {
|
||||
std::lock_guard<std::mutex> lock(completion_port_lock_);
|
||||
|
|
|
@ -87,7 +87,7 @@ class XFile : public XObject {
|
|||
vfs::Device* device() const { return file_->entry()->device(); }
|
||||
vfs::Entry* entry() const { return file_->entry(); }
|
||||
vfs::File* file() const { return file_; }
|
||||
uint32_t file_access() const { return file_access_; }
|
||||
uint32_t file_access() const { return file_->file_access(); }
|
||||
|
||||
const std::string& path() const { return file_->entry()->path(); }
|
||||
const std::string& name() const { return file_->entry()->name(); }
|
||||
|
@ -105,19 +105,24 @@ class XFile : public XObject {
|
|||
size_t* out_bytes_written, uint32_t apc_context);
|
||||
|
||||
xe::threading::WaitHandle* GetWaitHandle() override {
|
||||
return async_event_->GetWaitHandle();
|
||||
return async_event_.get();
|
||||
}
|
||||
|
||||
void RegisterIOCompletionPort(uint32_t key, object_ref<XIOCompletion> port);
|
||||
void RemoveIOCompletionPort(uint32_t key);
|
||||
|
||||
bool Save(ByteStream* stream);
|
||||
static object_ref<XFile> Restore(KernelState* kernel_state,
|
||||
ByteStream* stream);
|
||||
|
||||
protected:
|
||||
void NotifyIOCompletionPorts(XIOCompletion::IONotification& notification);
|
||||
|
||||
private:
|
||||
XFile();
|
||||
|
||||
vfs::File* file_ = nullptr;
|
||||
uint32_t file_access_ = 0;
|
||||
XEvent* async_event_ = nullptr;
|
||||
std::unique_ptr<threading::Event> async_event_ = nullptr;
|
||||
|
||||
std::mutex completion_port_lock_;
|
||||
std::vector<std::pair<uint32_t, object_ref<XIOCompletion>>> completion_ports_;
|
||||
|
|
|
@ -133,7 +133,7 @@ object_ref<XObject> XObject::Restore(KernelState* kernel_state, Type type,
|
|||
case kTypeEvent:
|
||||
return XEvent::Restore(kernel_state, stream);
|
||||
case kTypeFile:
|
||||
break;
|
||||
return XFile::Restore(kernel_state, stream);
|
||||
case kTypeIOCompletion:
|
||||
break;
|
||||
case kTypeModule:
|
||||
|
|
Loading…
Reference in New Issue