[*] Pin overlapped structure until async IO completion
This commit is contained in:
parent
2382f75759
commit
03368d262f
@ -36,7 +36,7 @@ namespace Aurora::IO::FS
|
||||
AuSPtr<FileHandle> handle_;
|
||||
};
|
||||
|
||||
class NtAsyncFileTransaction : public IAsyncTransaction
|
||||
class NtAsyncFileTransaction : public IAsyncTransaction, std::enable_shared_from_this<NtAsyncFileTransaction>
|
||||
{
|
||||
public:
|
||||
~NtAsyncFileTransaction();
|
||||
@ -57,10 +57,13 @@ namespace Aurora::IO::FS
|
||||
|
||||
HANDLE GetHandle();
|
||||
AuSPtr<FileHandle> GetFileHandle();
|
||||
|
||||
// Required for a very evil hack
|
||||
OVERLAPPED overlap_ {};
|
||||
private:
|
||||
AuSPtr<NtAsyncFileTransaction> pin_;
|
||||
AuSPtr<FileHandle> handle_;
|
||||
HANDLE event_ = INVALID_HANDLE_VALUE;
|
||||
OVERLAPPED overlap_ {};
|
||||
AuUInt32 lastAbstractStat_ {}, lastAbstractOffset_ {};
|
||||
bool latch_ {};
|
||||
AuSPtr<IAsyncFinishedSubscriber> sub_;
|
||||
@ -170,6 +173,16 @@ namespace Aurora::IO::FS
|
||||
}
|
||||
}
|
||||
|
||||
VOID WINAPI GenericCompletionRoutine(
|
||||
_In_ DWORD dwErrorCode,
|
||||
_In_ DWORD dwNumberOfBytesTransfered,
|
||||
_Inout_ LPOVERLAPPED lpOverlapped
|
||||
)
|
||||
{
|
||||
auto transaction = reinterpret_cast<NtAsyncFileTransaction *>(reinterpret_cast<AuUInt8*>(lpOverlapped) - offsetof(NtAsyncFileTransaction, overlap_));
|
||||
transaction->Complete();
|
||||
}
|
||||
|
||||
bool NtAsyncFileTransaction::StartRead(AuUInt64 offset, void *buffer, AuUInt32 length)
|
||||
{
|
||||
this->latch_ = {};
|
||||
@ -177,7 +190,8 @@ namespace Aurora::IO::FS
|
||||
this->lastAbstractOffset_ = offset;
|
||||
this->overlap_.Offset = offset & 0xFFFFFFFF;
|
||||
this->overlap_.OffsetHigh = (offset >> 32) & 0xFFFFFFFF;
|
||||
auto ret = ::ReadFile(this->handle_->handle, buffer, length, NULL, &overlap_);
|
||||
this->pin_ = AU_SHARED_FROM_THIS;
|
||||
auto ret = ::ReadFileEx(this->handle_->handle, buffer, length, &overlap_, GenericCompletionRoutine);
|
||||
return TranslateNtStatus(this, ret);
|
||||
}
|
||||
|
||||
@ -188,7 +202,8 @@ namespace Aurora::IO::FS
|
||||
this->lastAbstractOffset_ = offset;
|
||||
this->overlap_.Offset = offset & 0xFFFFFFFF;
|
||||
this->overlap_.OffsetHigh = (offset >> 32) & 0xFFFFFFFF;
|
||||
auto ret = ::WriteFile(this->handle_->handle, buffer, length, NULL, &overlap_);
|
||||
this->pin_ = AU_SHARED_FROM_THIS;
|
||||
auto ret = ::WriteFileEx(this->handle_->handle, buffer, length, &overlap_, GenericCompletionRoutine);
|
||||
return TranslateNtStatus(this, ret);
|
||||
}
|
||||
|
||||
@ -199,6 +214,8 @@ namespace Aurora::IO::FS
|
||||
return;
|
||||
}
|
||||
|
||||
this->pin_ = {};
|
||||
|
||||
if (this->sub_)
|
||||
{
|
||||
DWORD read {};
|
||||
|
Loading…
Reference in New Issue
Block a user