[+] AuIO::IIOHandle
This commit is contained in:
parent
0cf38d5fcd
commit
7e2aa2de3d
@ -15,4 +15,10 @@ namespace Aurora::IO::FS
|
|||||||
bool bDirectIO = true, // true disables buffering under Win32
|
bool bDirectIO = true, // true disables buffering under Win32
|
||||||
// true enables non-blocking ticks under Linux aio by bypassing the kernels cache
|
// true enables non-blocking ticks under Linux aio by bypassing the kernels cache
|
||||||
EFileAdvisoryLockLevel lock = EFileAdvisoryLockLevel::eNoSafety);
|
EFileAdvisoryLockLevel lock = EFileAdvisoryLockLevel::eNoSafety);
|
||||||
|
|
||||||
|
#if defined(AUX_FSAOPEX)
|
||||||
|
AUKN_SYM AuSPtr<IAsyncTransaction> OpenDirectIOAsyncFileStreamFromHandle(AuSPtr<IIOHandle> pIOHandle);
|
||||||
|
|
||||||
|
AUKN_SYM AuSPtr<IAsyncTransaction> OpenBufferedAsyncFileStreamFromHandle(AuSPtr<IIOHandle> pIOHandle);
|
||||||
|
#endif
|
||||||
}
|
}
|
@ -18,4 +18,6 @@ namespace Aurora::IO::FS
|
|||||||
AUKN_SHARED_API(OpenWrite, IFileStream, const AuString &path, EFileAdvisoryLockLevel successPostAdvisoryLevel = EFileAdvisoryLockLevel::eBlockReadWrite);
|
AUKN_SHARED_API(OpenWrite, IFileStream, const AuString &path, EFileAdvisoryLockLevel successPostAdvisoryLevel = EFileAdvisoryLockLevel::eBlockReadWrite);
|
||||||
|
|
||||||
AUKN_SHARED_API(Open, IFileStream, const AuString &path, EFileOpenMode mode = EFileOpenMode::eRead, EFileAdvisoryLockLevel successPostAdvisoryLevel = EFileAdvisoryLockLevel::eBlockReadWrite);
|
AUKN_SHARED_API(Open, IFileStream, const AuString &path, EFileOpenMode mode = EFileOpenMode::eRead, EFileAdvisoryLockLevel successPostAdvisoryLevel = EFileAdvisoryLockLevel::eBlockReadWrite);
|
||||||
|
|
||||||
|
AUKN_SYM AuSPtr<IFileStream> OpenBlockingFileStreamFromHandle(AuSPtr<IIOHandle> pIOHandle);
|
||||||
}
|
}
|
@ -20,6 +20,8 @@
|
|||||||
#include "Async.hpp"
|
#include "Async.hpp"
|
||||||
#include "IOSleep.hpp"
|
#include "IOSleep.hpp"
|
||||||
|
|
||||||
|
#include "IOHandle.hpp"
|
||||||
|
|
||||||
#include "FS/FS.hpp"
|
#include "FS/FS.hpp"
|
||||||
#include "Net/Net.hpp"
|
#include "Net/Net.hpp"
|
||||||
#include "Character/Character.hpp"
|
#include "Character/Character.hpp"
|
||||||
|
129
Include/Aurora/IO/IOHandle.hpp
Normal file
129
Include/Aurora/IO/IOHandle.hpp
Normal file
@ -0,0 +1,129 @@
|
|||||||
|
/***
|
||||||
|
Copyright (C) 2023 J Reece Wilson (a/k/a "Reece"). All rights reserved.
|
||||||
|
|
||||||
|
File: IOHandle.hpp
|
||||||
|
Date: 2023-7-28
|
||||||
|
Author: Reece
|
||||||
|
***/
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "FS/EFileAdvisoryLockLevel.hpp"
|
||||||
|
#include "FS/EFileOpenMode.hpp"
|
||||||
|
|
||||||
|
namespace Aurora::IO
|
||||||
|
{
|
||||||
|
// Note: A handle is never disposable to prevent IO fd use after close
|
||||||
|
// You must ensure RAII and/or shared ownership release to dispose of the IO handle.
|
||||||
|
// This class is only intended to be an handle view; therefore, it is not possible to close the handle.
|
||||||
|
struct IIOHandle
|
||||||
|
{
|
||||||
|
struct HandleCreate
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* "Create"
|
||||||
|
*/
|
||||||
|
bool bFailIfNonEmptyFile {};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Lock level
|
||||||
|
*/
|
||||||
|
FS::EFileAdvisoryLockLevel eAdvisoryLevel;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Path
|
||||||
|
*/
|
||||||
|
const AuString &path;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Mode
|
||||||
|
*/
|
||||||
|
FS::EFileOpenMode eMode;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
bool bAlwaysCreateDirTree { true };
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Indicates the handle will be for use with IAsyncTransactions as opposed to IFileStream and AuProcess
|
||||||
|
*/
|
||||||
|
bool bAsyncHandle { false };
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Indicates the handle will only ever directly interface with the disk hardware as opposed to leveraging kernel assigned user shared memory
|
||||||
|
*/
|
||||||
|
bool bDirectIOMode { false };
|
||||||
|
|
||||||
|
cstatic HandleCreate Create(const AuString &path)
|
||||||
|
{
|
||||||
|
HandleCreate create(path);
|
||||||
|
create.bFailIfNonEmptyFile = true;
|
||||||
|
create.eMode = FS::EFileOpenMode::eReadWrite;
|
||||||
|
create.eAdvisoryLevel = FS::EFileAdvisoryLockLevel::eBlockReadWrite;
|
||||||
|
return AuMove(create);
|
||||||
|
}
|
||||||
|
|
||||||
|
cstatic HandleCreate ReadWrite(const AuString &path)
|
||||||
|
{
|
||||||
|
HandleCreate create(path);
|
||||||
|
create.eMode = FS::EFileOpenMode::eReadWrite;
|
||||||
|
create.eAdvisoryLevel = FS::EFileAdvisoryLockLevel::eBlockReadWrite;
|
||||||
|
return AuMove(create);
|
||||||
|
}
|
||||||
|
|
||||||
|
cstatic HandleCreate Read(const AuString &path)
|
||||||
|
{
|
||||||
|
HandleCreate read(path);
|
||||||
|
read.eMode = FS::EFileOpenMode::eRead;
|
||||||
|
read.eAdvisoryLevel = FS::EFileAdvisoryLockLevel::eBlockWrite;
|
||||||
|
return AuMove(read);
|
||||||
|
}
|
||||||
|
|
||||||
|
cstatic HandleCreate Open(const AuString &path)
|
||||||
|
{
|
||||||
|
HandleCreate read(path);
|
||||||
|
read.eMode = FS::EFileOpenMode::eRead;
|
||||||
|
read.eAdvisoryLevel = FS::EFileAdvisoryLockLevel::eBlockReadWrite;
|
||||||
|
return AuMove(read);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline HandleCreate(const AuString &path) :
|
||||||
|
path(path)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
virtual bool InitFromHandle(AuSPtr<IIOHandle> pHandle) = 0;
|
||||||
|
|
||||||
|
virtual bool InitFromPath(HandleCreate create) = 0;
|
||||||
|
|
||||||
|
virtual bool InitFromCopy(AuUInt64 uOSHandle) = 0;
|
||||||
|
|
||||||
|
virtual bool InitFromMove(AuUInt64 uOSHandle) = 0;
|
||||||
|
|
||||||
|
virtual bool InitFromPair(AuUInt64 uOSReadHandle, AuUInt64 uOSWriteHandle) = 0;
|
||||||
|
|
||||||
|
virtual bool InitFromPairMove(AuOptionalEx<AuUInt64> uOSReadHandle,
|
||||||
|
AuOptionalEx<AuUInt64> uOSWriteHandle) = 0;
|
||||||
|
|
||||||
|
virtual AuUInt64 GetOSHandle() = 0;
|
||||||
|
|
||||||
|
virtual AuUInt64 GetOSReadHandle() = 0;
|
||||||
|
|
||||||
|
virtual AuOptionalEx<AuUInt64> GetOSReadHandleSafe() = 0;
|
||||||
|
|
||||||
|
virtual AuUInt64 GetOSWriteHandle() = 0;
|
||||||
|
|
||||||
|
virtual AuOptionalEx<AuUInt64> GetOSWriteHandleSafe() = 0;
|
||||||
|
|
||||||
|
virtual bool IsValid() = 0;
|
||||||
|
|
||||||
|
virtual bool HasUniqueWriteHandle() = 0;
|
||||||
|
|
||||||
|
virtual bool IsAsync() = 0;
|
||||||
|
|
||||||
|
virtual AuString GetPath() = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
AUKN_SHARED_SOO(IOHandle, IIOHandle, 256);
|
||||||
|
}
|
@ -124,7 +124,7 @@ namespace Aurora::Memory
|
|||||||
{
|
{
|
||||||
if (buffer.length)
|
if (buffer.length)
|
||||||
{
|
{
|
||||||
this->base = FAlloc<AuUInt8 *>(buffer.length);
|
this->base = ZAlloc<AuUInt8 *>(buffer.length);
|
||||||
}
|
}
|
||||||
this->scaleSize = buffer.scaleSize;
|
this->scaleSize = buffer.scaleSize;
|
||||||
this->flagCircular = buffer.flagCircular;
|
this->flagCircular = buffer.flagCircular;
|
||||||
@ -160,7 +160,7 @@ namespace Aurora::Memory
|
|||||||
inline ByteBuffer(const void *in, AuUInt length, bool circular = false, bool expandable = false) : flagCircular(circular), flagExpandable(expandable), flagReadError(0), flagWriteError(0)
|
inline ByteBuffer(const void *in, AuUInt length, bool circular = false, bool expandable = false) : flagCircular(circular), flagExpandable(expandable), flagReadError(0), flagWriteError(0)
|
||||||
{
|
{
|
||||||
this->scaleSize = kBufferInitialPower;
|
this->scaleSize = kBufferInitialPower;
|
||||||
this->base = length ? FAlloc<AuUInt8 *>(length) : nullptr;
|
this->base = length ? ZAlloc<AuUInt8 *>(length) : nullptr;
|
||||||
if (!this->base)
|
if (!this->base)
|
||||||
{
|
{
|
||||||
Reset();
|
Reset();
|
||||||
@ -181,7 +181,7 @@ namespace Aurora::Memory
|
|||||||
inline ByteBuffer(const AuList<AuUInt8> &vector, bool circular = false, bool expandable = false) : flagCircular(circular), flagExpandable(expandable), flagReadError(0), flagWriteError(0)
|
inline ByteBuffer(const AuList<AuUInt8> &vector, bool circular = false, bool expandable = false) : flagCircular(circular), flagExpandable(expandable), flagReadError(0), flagWriteError(0)
|
||||||
{
|
{
|
||||||
this->scaleSize = kBufferInitialPower;
|
this->scaleSize = kBufferInitialPower;
|
||||||
this->base = vector.size() ? FAlloc<AuUInt8 *>(vector.size()) : nullptr;
|
this->base = vector.size() ? ZAlloc<AuUInt8 *>(vector.size()) : nullptr;
|
||||||
if (!this->base)
|
if (!this->base)
|
||||||
{
|
{
|
||||||
Reset();
|
Reset();
|
||||||
|
@ -31,7 +31,7 @@ namespace Aurora::Memory
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
this->base = fast ? FAlloc<AuUInt8 *>(length) : ZAlloc<AuUInt8 *>(length);
|
this->base = ZAlloc<AuUInt8 *>(length);
|
||||||
if (!this->base)
|
if (!this->base)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
@ -65,7 +65,7 @@ namespace Aurora::Memory
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
this->base = fast ? FAlloc<AuUInt8 *>(length, alignment) : ZAlloc<AuUInt8 *>(length, alignment);
|
this->base = ZAlloc<AuUInt8 *>(length, alignment);
|
||||||
if (!this->base)
|
if (!this->base)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
|
260
Source/IO/AuIOHandle.NT.cpp
Normal file
260
Source/IO/AuIOHandle.NT.cpp
Normal file
@ -0,0 +1,260 @@
|
|||||||
|
/***
|
||||||
|
Copyright (C) 2023 J Reece Wilson (a/k/a "Reece"). All rights reserved.
|
||||||
|
|
||||||
|
File: AuIOHandle.NT.cpp
|
||||||
|
Date: 2023-7-28
|
||||||
|
Author: Reece
|
||||||
|
***/
|
||||||
|
#include <RuntimeInternal.hpp>
|
||||||
|
#include "AuIOHandle.hpp"
|
||||||
|
#include "AuIOHandle.NT.hpp"
|
||||||
|
|
||||||
|
#include "FS/FS.hpp"
|
||||||
|
#include "FS/FileAdvisory.NT.hpp"
|
||||||
|
|
||||||
|
namespace Aurora::IO
|
||||||
|
{
|
||||||
|
AuUInt64 AFileHandle::DupHandle(AuUInt64 uOSHandle, bool bWriteAccess)
|
||||||
|
{
|
||||||
|
HANDLE hTargetHandle = (HANDLE)uOSHandle;
|
||||||
|
HANDLE hTargetProcess = ::GetCurrentProcess();
|
||||||
|
HANDLE hHandle {};
|
||||||
|
|
||||||
|
if (!::DuplicateHandle(hTargetProcess,
|
||||||
|
hTargetHandle,
|
||||||
|
hTargetProcess,
|
||||||
|
&hHandle,
|
||||||
|
bWriteAccess ? GENERIC_WRITE | GENERIC_READ : GENERIC_READ,
|
||||||
|
FALSE,
|
||||||
|
FALSE))
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return AuUInt64(hHandle);
|
||||||
|
}
|
||||||
|
|
||||||
|
void AFileHandle::CloseHandle(AuUInt64 uOSHandle)
|
||||||
|
{
|
||||||
|
HANDLE hHandle = (HANDLE)uOSHandle;
|
||||||
|
AuWin32CloseHandle(hHandle);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct NTIOHandle final : AFileHandle
|
||||||
|
{
|
||||||
|
bool InitFromPath(HandleCreate create) override
|
||||||
|
{
|
||||||
|
HANDLE hFileHandle;
|
||||||
|
|
||||||
|
DWORD dwFlags {};
|
||||||
|
DWORD dwShare {};
|
||||||
|
|
||||||
|
if (create.path.empty())
|
||||||
|
{
|
||||||
|
SysPushErrorArg("Cannot open an IO handle to the provided empty path");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!FS::EFileOpenModeIsValid(create.eMode))
|
||||||
|
{
|
||||||
|
SysPushErrorParam("Invalid open mode");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!FS::EFileAdvisoryLockLevelIsValid(create.eAdvisoryLevel))
|
||||||
|
{
|
||||||
|
SysPushErrorParam("Invalid lock mode");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto pathex = FS::NormalizePathRet(create.path);
|
||||||
|
if (pathex.empty())
|
||||||
|
{
|
||||||
|
SysPushErrorMemory();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto win32Path = Locale::ConvertFromUTF8(pathex);
|
||||||
|
if (win32Path.empty())
|
||||||
|
{
|
||||||
|
SysPushErrorMemory();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
hFileHandle = INVALID_HANDLE_VALUE;
|
||||||
|
|
||||||
|
dwShare = FS::NtLockAdvisoryToShare(create.eAdvisoryLevel);
|
||||||
|
|
||||||
|
if (create.bAsyncHandle)
|
||||||
|
{
|
||||||
|
dwFlags |= FILE_FLAG_OVERLAPPED;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (create.bDirectIOMode)
|
||||||
|
{
|
||||||
|
dwFlags |= FILE_FLAG_NO_BUFFERING;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!dwFlags)
|
||||||
|
{
|
||||||
|
dwFlags |= FILE_ATTRIBUTE_NORMAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (create.eMode)
|
||||||
|
{
|
||||||
|
case FS::EFileOpenMode::eRead:
|
||||||
|
{
|
||||||
|
hFileHandle = ::CreateFileW(win32Path.c_str(),
|
||||||
|
GENERIC_READ,
|
||||||
|
dwShare,
|
||||||
|
NULL,
|
||||||
|
OPEN_EXISTING,
|
||||||
|
dwFlags,
|
||||||
|
NULL);
|
||||||
|
|
||||||
|
if (hFileHandle != INVALID_HANDLE_VALUE)
|
||||||
|
{
|
||||||
|
this->uOSReadHandle = AuUInt64(hFileHandle);
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case FS::EFileOpenMode::eReadWrite:
|
||||||
|
{
|
||||||
|
if (create.bAlwaysCreateDirTree)
|
||||||
|
{
|
||||||
|
FS::CreateDirectories(pathex, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (create.bFailIfNonEmptyFile)
|
||||||
|
{
|
||||||
|
hFileHandle = ::CreateFileW(win32Path.c_str(),
|
||||||
|
GENERIC_WRITE | GENERIC_READ | DELETE,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
CREATE_NEW,
|
||||||
|
dwFlags,
|
||||||
|
NULL);
|
||||||
|
|
||||||
|
if (hFileHandle == INVALID_HANDLE_VALUE)
|
||||||
|
{
|
||||||
|
if (AuFS::FileExists(pathex.c_str()))
|
||||||
|
{
|
||||||
|
SysPushErrorResourceExists("File {} already exists", create.path);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
hFileHandle = ::CreateFileW(win32Path.c_str(),
|
||||||
|
GENERIC_WRITE | GENERIC_READ | DELETE,
|
||||||
|
dwShare,
|
||||||
|
NULL,
|
||||||
|
OPEN_EXISTING,
|
||||||
|
dwFlags,
|
||||||
|
NULL);
|
||||||
|
|
||||||
|
if (hFileHandle == INVALID_HANDLE_VALUE)
|
||||||
|
{
|
||||||
|
hFileHandle = ::CreateFileW(win32Path.c_str(),
|
||||||
|
GENERIC_WRITE | GENERIC_READ | DELETE,
|
||||||
|
dwShare,
|
||||||
|
NULL,
|
||||||
|
CREATE_NEW,
|
||||||
|
dwFlags,
|
||||||
|
NULL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hFileHandle != INVALID_HANDLE_VALUE)
|
||||||
|
{
|
||||||
|
this->uOSReadHandle = AuUInt64(hFileHandle);
|
||||||
|
this->uOSWriteHandle = AuUInt64(hFileHandle);
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case FS::EFileOpenMode::eWrite:
|
||||||
|
{
|
||||||
|
if (create.bAlwaysCreateDirTree)
|
||||||
|
{
|
||||||
|
FS::CreateDirectories(pathex, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (create.bFailIfNonEmptyFile)
|
||||||
|
{
|
||||||
|
hFileHandle = ::CreateFileW(win32Path.c_str(),
|
||||||
|
GENERIC_WRITE | DELETE,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
CREATE_NEW,
|
||||||
|
dwFlags,
|
||||||
|
NULL);
|
||||||
|
|
||||||
|
if (hFileHandle == INVALID_HANDLE_VALUE)
|
||||||
|
{
|
||||||
|
if (AuFS::FileExists(pathex.c_str()))
|
||||||
|
{
|
||||||
|
SysPushErrorResourceExists("File {} already exists", create.path);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
hFileHandle = ::CreateFileW(win32Path.c_str(),
|
||||||
|
GENERIC_WRITE | FILE_READ_ATTRIBUTES | DELETE,
|
||||||
|
dwShare,
|
||||||
|
NULL,
|
||||||
|
OPEN_EXISTING,
|
||||||
|
dwFlags,
|
||||||
|
NULL);
|
||||||
|
|
||||||
|
if (hFileHandle == INVALID_HANDLE_VALUE)
|
||||||
|
{
|
||||||
|
hFileHandle = ::CreateFileW(win32Path.c_str(),
|
||||||
|
GENERIC_WRITE | DELETE,
|
||||||
|
dwShare,
|
||||||
|
NULL,
|
||||||
|
CREATE_NEW,
|
||||||
|
dwFlags,
|
||||||
|
NULL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hFileHandle != INVALID_HANDLE_VALUE)
|
||||||
|
{
|
||||||
|
this->uOSWriteHandle = AuUInt64(hFileHandle);
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hFileHandle == INVALID_HANDLE_VALUE)
|
||||||
|
{
|
||||||
|
SysPushErrorIO("Couldn't open: {}", create.path);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
this->bIsAsync = create.bAsyncHandle;
|
||||||
|
|
||||||
|
this->path = create.path;
|
||||||
|
|
||||||
|
return this->IsValid();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
AUKN_SYM IIOHandle *IOHandleNew()
|
||||||
|
{
|
||||||
|
return _new NTIOHandle();
|
||||||
|
}
|
||||||
|
|
||||||
|
AUKN_SYM void IOHandleRelease(IIOHandle *pIOHandle)
|
||||||
|
{
|
||||||
|
AuSafeDelete<NTIOHandle *>(pIOHandle);
|
||||||
|
}
|
||||||
|
|
||||||
|
AUROXTL_INTERFACE_SOO_SRC_EX(AURORA_SYMBOL_EXPORT, IOHandle, NTIOHandle)
|
||||||
|
}
|
13
Source/IO/AuIOHandle.NT.hpp
Normal file
13
Source/IO/AuIOHandle.NT.hpp
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
/***
|
||||||
|
Copyright (C) 2023 J Reece Wilson (a/k/a "Reece"). All rights reserved.
|
||||||
|
|
||||||
|
File: AuIOHandle.NT.hpp
|
||||||
|
Date: 2023-7-28
|
||||||
|
Author: Reece
|
||||||
|
***/
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
namespace Aurora::IO
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
174
Source/IO/AuIOHandle.cpp
Normal file
174
Source/IO/AuIOHandle.cpp
Normal file
@ -0,0 +1,174 @@
|
|||||||
|
/***
|
||||||
|
Copyright (C) 2023 J Reece Wilson (a/k/a "Reece"). All rights reserved.
|
||||||
|
|
||||||
|
File: AuIOHandle.cpp
|
||||||
|
Date: 2023-7-28
|
||||||
|
Author: Reece
|
||||||
|
***/
|
||||||
|
#include <RuntimeInternal.hpp>
|
||||||
|
#include "AuIOHandle.hpp"
|
||||||
|
|
||||||
|
namespace Aurora::IO
|
||||||
|
{
|
||||||
|
AFileHandle::~AFileHandle()
|
||||||
|
{
|
||||||
|
if (this->uOSWriteHandle.HasValue() && this->uOSReadHandle.HasValue() &&
|
||||||
|
this->uOSReadHandle.Value() == this->uOSWriteHandle.Value())
|
||||||
|
{
|
||||||
|
this->CloseHandle(this->uOSReadHandle.value());
|
||||||
|
AuResetMember(this->uOSReadHandle);
|
||||||
|
AuResetMember(this->uOSWriteHandle);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this->uOSReadHandle)
|
||||||
|
{
|
||||||
|
this->CloseHandle(this->uOSReadHandle.value());
|
||||||
|
AuResetMember(this->uOSReadHandle);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this->uOSWriteHandle)
|
||||||
|
{
|
||||||
|
this->CloseHandle(this->uOSWriteHandle.value());
|
||||||
|
AuResetMember(this->uOSWriteHandle);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool AFileHandle::InitFromHandle(AuSPtr<IIOHandle> pHandle)
|
||||||
|
{
|
||||||
|
auto pSrc = AuStaticCast<AFileHandle>(pHandle);
|
||||||
|
auto pDest = this;
|
||||||
|
|
||||||
|
if (this->IsValid())
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
pDest->pThat = pHandle;
|
||||||
|
pDest->uOSReadHandle = pSrc->uOSReadHandle;
|
||||||
|
pDest->uOSWriteHandle = pSrc->uOSWriteHandle;
|
||||||
|
pDest->bIsAsync = pSrc->bIsAsync;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool AFileHandle::InitFromCopy(AuUInt64 uOSHandle)
|
||||||
|
{
|
||||||
|
if (this->IsValid())
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (auto uOSWriteHandle = this->DupHandle(uOSHandle, true))
|
||||||
|
{
|
||||||
|
this->uOSReadHandle = uOSWriteHandle;
|
||||||
|
this->uOSWriteHandle = uOSWriteHandle;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool AFileHandle::InitFromMove(AuUInt64 uOSHandle)
|
||||||
|
{
|
||||||
|
if (this->IsValid())
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
this->uOSReadHandle = uOSHandle;
|
||||||
|
this->uOSWriteHandle = uOSHandle;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool AFileHandle::InitFromPair(AuUInt64 uOSReadHandle,
|
||||||
|
AuUInt64 uOSWriteHandle)
|
||||||
|
{
|
||||||
|
if (this->IsValid())
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (auto uOSReadHandle2 = this->DupHandle(uOSReadHandle, false))
|
||||||
|
{
|
||||||
|
this->uOSReadHandle = uOSReadHandle2;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
if (auto uOSWriteHandle2 = this->DupHandle(uOSWriteHandle, true))
|
||||||
|
{
|
||||||
|
this->uOSWriteHandle = uOSWriteHandle2;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
this->CloseHandle(this->uOSReadHandle);
|
||||||
|
AuResetMember(this->uOSReadHandle);
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool AFileHandle::InitFromPairMove(AuOptionalEx<AuUInt64> uOSReadHandle,
|
||||||
|
AuOptionalEx<AuUInt64> uOSWriteHandle)
|
||||||
|
{
|
||||||
|
if (this->IsValid())
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
this->uOSReadHandle = uOSReadHandle;
|
||||||
|
this->uOSWriteHandle = uOSWriteHandle;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
AuUInt64 AFileHandle::GetOSHandle()
|
||||||
|
{
|
||||||
|
return this->uOSReadHandle.ValueOr(this->uOSWriteHandle.Value());
|
||||||
|
}
|
||||||
|
|
||||||
|
AuUInt64 AFileHandle::GetOSReadHandle()
|
||||||
|
{
|
||||||
|
return this->uOSReadHandle.value();
|
||||||
|
}
|
||||||
|
|
||||||
|
AuOptionalEx<AuUInt64> AFileHandle::GetOSReadHandleSafe()
|
||||||
|
{
|
||||||
|
return this->uOSReadHandle;
|
||||||
|
}
|
||||||
|
|
||||||
|
AuUInt64 AFileHandle::GetOSWriteHandle()
|
||||||
|
{
|
||||||
|
return this->uOSWriteHandle.Value();
|
||||||
|
}
|
||||||
|
|
||||||
|
AuOptionalEx<AuUInt64> AFileHandle::GetOSWriteHandleSafe()
|
||||||
|
{
|
||||||
|
return this->uOSWriteHandle;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool AFileHandle::IsValid()
|
||||||
|
{
|
||||||
|
return this->uOSReadHandle.HasValue() ||
|
||||||
|
this->uOSWriteHandle.HasValue();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool AFileHandle::HasUniqueWriteHandle()
|
||||||
|
{
|
||||||
|
return this->uOSWriteHandle.HasValue();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool AFileHandle::IsAsync()
|
||||||
|
{
|
||||||
|
return this->bIsAsync;
|
||||||
|
}
|
||||||
|
|
||||||
|
AuString AFileHandle::GetPath()
|
||||||
|
{
|
||||||
|
return this->path;
|
||||||
|
}
|
||||||
|
}
|
60
Source/IO/AuIOHandle.hpp
Normal file
60
Source/IO/AuIOHandle.hpp
Normal file
@ -0,0 +1,60 @@
|
|||||||
|
/***
|
||||||
|
Copyright (C) 2023 J Reece Wilson (a/k/a "Reece"). All rights reserved.
|
||||||
|
|
||||||
|
File: AuIOHandle.hpp
|
||||||
|
Date: 2023-7-28
|
||||||
|
Author: Reece
|
||||||
|
***/
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
namespace Aurora::IO
|
||||||
|
{
|
||||||
|
struct AFileHandle : IIOHandle
|
||||||
|
{
|
||||||
|
virtual ~AFileHandle();
|
||||||
|
|
||||||
|
bool InitFromHandle(AuSPtr<IIOHandle> pHandle) override;
|
||||||
|
|
||||||
|
bool InitFromCopy(AuUInt64 uOSHandle) override;
|
||||||
|
|
||||||
|
bool InitFromMove(AuUInt64 uOSHandle) override;
|
||||||
|
|
||||||
|
bool InitFromPair(AuUInt64 uOSReadHandle,
|
||||||
|
AuUInt64 uOSWriteHandle) override;
|
||||||
|
|
||||||
|
bool InitFromPairMove(AuOptionalEx<AuUInt64> uOSReadHandle,
|
||||||
|
AuOptionalEx<AuUInt64> uOSWriteHandle) override;
|
||||||
|
|
||||||
|
AuUInt64 GetOSHandle() override;
|
||||||
|
|
||||||
|
AuUInt64 GetOSReadHandle() override;
|
||||||
|
|
||||||
|
AuOptionalEx<AuUInt64> GetOSReadHandleSafe() override;
|
||||||
|
|
||||||
|
AuUInt64 GetOSWriteHandle() override;
|
||||||
|
|
||||||
|
AuOptionalEx<AuUInt64> GetOSWriteHandleSafe() override;
|
||||||
|
|
||||||
|
bool IsValid() override;
|
||||||
|
|
||||||
|
bool HasUniqueWriteHandle() override;
|
||||||
|
|
||||||
|
bool IsAsync() override;
|
||||||
|
|
||||||
|
AuString GetPath() override;
|
||||||
|
|
||||||
|
AuOptionalEx<AuUInt64> uOSWriteHandle;
|
||||||
|
AuOptionalEx<AuUInt64> uOSReadHandle;
|
||||||
|
AuSPtr<IIOHandle> pThat;
|
||||||
|
bool bIsAsync {};
|
||||||
|
AuString path;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
// Implement me:
|
||||||
|
|
||||||
|
// bool InitFromPath(HandleCreate create) override;
|
||||||
|
|
||||||
|
static AuUInt64 DupHandle(AuUInt64 uOSHandle, bool bWriteAccess);
|
||||||
|
static void CloseHandle(AuUInt64 uOSHandle);
|
||||||
|
};
|
||||||
|
}
|
@ -62,105 +62,14 @@ namespace Aurora::IO::FS
|
|||||||
AuWin32CloseHandle(this->event);
|
AuWin32CloseHandle(this->event);
|
||||||
}
|
}
|
||||||
|
|
||||||
FileHandle::~FileHandle()
|
AuSPtr<IIOHandle> NtAsyncFileStream::GetHandle()
|
||||||
{
|
{
|
||||||
if (this->bNoOwns)
|
return this->pHandle_;
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this->writeHandle != this->handle)
|
|
||||||
{
|
|
||||||
AuWin32CloseHandle(this->writeHandle);
|
|
||||||
}
|
|
||||||
|
|
||||||
this->writeHandle = INVALID_HANDLE_VALUE;
|
|
||||||
AuWin32CloseHandle(this->handle);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool FileHandle::Init(const AuString &path, EFileOpenMode openMode, bool directIO, EFileAdvisoryLockLevel lock)
|
void NtAsyncFileStream::Init(const AuSPtr<IIOHandle> &pHandle)
|
||||||
{
|
{
|
||||||
HANDLE fileHandle;
|
this->pHandle_ = pHandle;
|
||||||
|
|
||||||
auto pathex = NormalizePathRet(path);
|
|
||||||
if (pathex.empty())
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto win32Path = Locale::ConvertFromUTF8(pathex);
|
|
||||||
if (win32Path.empty())
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto flags = FILE_FLAG_OVERLAPPED;
|
|
||||||
|
|
||||||
if (directIO)
|
|
||||||
{
|
|
||||||
flags |= FILE_FLAG_NO_BUFFERING;
|
|
||||||
}
|
|
||||||
|
|
||||||
fileHandle = INVALID_HANDLE_VALUE;
|
|
||||||
|
|
||||||
switch (openMode)
|
|
||||||
{
|
|
||||||
case EFileOpenMode::eRead:
|
|
||||||
{
|
|
||||||
fileHandle = CreateFileW(win32Path.c_str(), GENERIC_READ, NtLockAdvisoryToShare(lock), NULL, OPEN_EXISTING, flags, NULL);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case EFileOpenMode::eReadWrite:
|
|
||||||
{
|
|
||||||
CreateDirectories(pathex, true);
|
|
||||||
fileHandle = CreateFileW(win32Path.c_str(), GENERIC_WRITE | GENERIC_READ, NtLockAdvisoryToShare(lock), NULL, OPEN_ALWAYS, flags, NULL);
|
|
||||||
if (fileHandle == INVALID_HANDLE_VALUE)
|
|
||||||
{
|
|
||||||
fileHandle = CreateFileW(win32Path.c_str(), GENERIC_WRITE | GENERIC_READ, NtLockAdvisoryToShare(lock), NULL, CREATE_ALWAYS, flags, NULL);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case EFileOpenMode::eWrite:
|
|
||||||
{
|
|
||||||
CreateDirectories(pathex, true);
|
|
||||||
fileHandle = CreateFileW(win32Path.c_str(), GENERIC_WRITE | FILE_READ_ATTRIBUTES, NtLockAdvisoryToShare(lock), NULL, OPEN_ALWAYS, flags, NULL);
|
|
||||||
if (fileHandle == INVALID_HANDLE_VALUE)
|
|
||||||
{
|
|
||||||
fileHandle = CreateFileW(win32Path.c_str(), GENERIC_WRITE | GENERIC_READ, NtLockAdvisoryToShare(lock), NULL, CREATE_ALWAYS, flags, NULL);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (fileHandle == INVALID_HANDLE_VALUE)
|
|
||||||
{
|
|
||||||
SysPushErrorIO("Missing file: {}", path);
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
|
|
||||||
this->directIO = directIO;
|
|
||||||
this->handle = fileHandle;
|
|
||||||
this->writeHandle = fileHandle;
|
|
||||||
this->readOnly = openMode == EFileOpenMode::eRead;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void FileHandle::Init(HANDLE read, HANDLE write)
|
|
||||||
{
|
|
||||||
this->directIO = true;
|
|
||||||
this->handle = read;
|
|
||||||
this->writeHandle = write;
|
|
||||||
this->readOnly = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
AuSPtr<FileHandle> NtAsyncFileStream::GetHandle()
|
|
||||||
{
|
|
||||||
return handle_;
|
|
||||||
}
|
|
||||||
|
|
||||||
void NtAsyncFileStream::Init(const AuSPtr<FileHandle> &handle)
|
|
||||||
{
|
|
||||||
this->handle_ = handle;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
AuSPtr<IAsyncTransaction> NtAsyncFileStream::NewTransaction()
|
AuSPtr<IAsyncTransaction> NtAsyncFileStream::NewTransaction()
|
||||||
@ -171,7 +80,7 @@ namespace Aurora::IO::FS
|
|||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!shared->Init(this->handle_))
|
if (!shared->InitWeak(this->pHandle_))
|
||||||
{
|
{
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
@ -184,13 +93,15 @@ namespace Aurora::IO::FS
|
|||||||
LARGE_INTEGER i {};
|
LARGE_INTEGER i {};
|
||||||
i.QuadPart = length;
|
i.QuadPart = length;
|
||||||
|
|
||||||
if (!SetFilePointerEx(this->handle_->handle, i, nullptr, FILE_BEGIN))
|
auto hHandle = (HANDLE)this->pHandle_->GetOSHandle();
|
||||||
|
|
||||||
|
if (!SetFilePointerEx(hHandle, i, nullptr, FILE_BEGIN))
|
||||||
{
|
{
|
||||||
SysPushErrorIO();
|
SysPushErrorIO();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return SetEndOfFile(this->handle_->handle);
|
return SetEndOfFile(hHandle);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool NtAsyncFileStream::BlockingRead(AuUInt64 offset, const Memory::MemoryViewStreamWrite ¶meters)
|
bool NtAsyncFileStream::BlockingRead(AuUInt64 offset, const Memory::MemoryViewStreamWrite ¶meters)
|
||||||
@ -198,12 +109,15 @@ namespace Aurora::IO::FS
|
|||||||
LARGE_INTEGER i {};
|
LARGE_INTEGER i {};
|
||||||
i.QuadPart = offset;
|
i.QuadPart = offset;
|
||||||
|
|
||||||
if (this->handle_->bReadLock)
|
auto hOptSafe = this->pHandle_->GetOSReadHandleSafe();
|
||||||
|
if (!hOptSafe)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!SetFilePointerEx(this->handle_->handle, i, nullptr, FILE_BEGIN))
|
auto hHandle = (HANDLE)hOptSafe.Value();
|
||||||
|
|
||||||
|
if (!SetFilePointerEx(hHandle, i, nullptr, FILE_BEGIN))
|
||||||
{
|
{
|
||||||
SysPushErrorIO();
|
SysPushErrorIO();
|
||||||
return false;
|
return false;
|
||||||
@ -213,7 +127,7 @@ namespace Aurora::IO::FS
|
|||||||
a.hEvent = CreateEventA(NULL, true, 0, NULL);
|
a.hEvent = CreateEventA(NULL, true, 0, NULL);
|
||||||
|
|
||||||
DWORD read;
|
DWORD read;
|
||||||
if (!::ReadFile(this->handle_->handle, parameters.ptr, parameters.length, NULL, &a) &&
|
if (!::ReadFile(hHandle, parameters.ptr, parameters.length, NULL, &a) &&
|
||||||
::GetLastError() != ERROR_IO_PENDING)
|
::GetLastError() != ERROR_IO_PENDING)
|
||||||
{
|
{
|
||||||
SysPushErrorIO();
|
SysPushErrorIO();
|
||||||
@ -222,7 +136,7 @@ namespace Aurora::IO::FS
|
|||||||
}
|
}
|
||||||
|
|
||||||
::WaitForSingleObject(a.hEvent, 0);
|
::WaitForSingleObject(a.hEvent, 0);
|
||||||
if (!::GetOverlappedResult(this->handle_->handle, &a, &read, true))
|
if (!::GetOverlappedResult(hHandle, &a, &read, true))
|
||||||
{
|
{
|
||||||
::CloseHandle(a.hEvent);
|
::CloseHandle(a.hEvent);
|
||||||
return false;
|
return false;
|
||||||
@ -238,12 +152,15 @@ namespace Aurora::IO::FS
|
|||||||
LARGE_INTEGER i {};
|
LARGE_INTEGER i {};
|
||||||
i.QuadPart = offset;
|
i.QuadPart = offset;
|
||||||
|
|
||||||
if (this->handle_->bWriteLock)
|
auto hOptSafe = this->pHandle_->GetOSWriteHandleSafe();
|
||||||
|
if (!hOptSafe)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!SetFilePointerEx(this->handle_->handle, i, nullptr, FILE_BEGIN))
|
auto hHandle = (HANDLE)hOptSafe.Value();
|
||||||
|
|
||||||
|
if (!SetFilePointerEx(hHandle, i, nullptr, FILE_BEGIN))
|
||||||
{
|
{
|
||||||
SysPushErrorIO();
|
SysPushErrorIO();
|
||||||
return false;
|
return false;
|
||||||
@ -253,7 +170,7 @@ namespace Aurora::IO::FS
|
|||||||
a.hEvent = CreateEventA(NULL, true, 0, NULL);
|
a.hEvent = CreateEventA(NULL, true, 0, NULL);
|
||||||
|
|
||||||
DWORD read;
|
DWORD read;
|
||||||
if (!::WriteFile(this->handle_->writeHandle, parameters.ptr, parameters.length, NULL, &a) &&
|
if (!::WriteFile(hHandle, parameters.ptr, parameters.length, NULL, &a) &&
|
||||||
::GetLastError() != ERROR_IO_PENDING)
|
::GetLastError() != ERROR_IO_PENDING)
|
||||||
{
|
{
|
||||||
SysPushErrorIO();
|
SysPushErrorIO();
|
||||||
@ -262,7 +179,7 @@ namespace Aurora::IO::FS
|
|||||||
}
|
}
|
||||||
|
|
||||||
::WaitForSingleObject(a.hEvent, 0);
|
::WaitForSingleObject(a.hEvent, 0);
|
||||||
if (!::GetOverlappedResult(this->handle_->writeHandle, &a, &read, true))
|
if (!::GetOverlappedResult(hHandle, &a, &read, true))
|
||||||
{
|
{
|
||||||
::CloseHandle(a.hEvent);
|
::CloseHandle(a.hEvent);
|
||||||
return false;
|
return false;
|
||||||
@ -273,7 +190,14 @@ namespace Aurora::IO::FS
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool NtAsyncFileTransaction::Init(const AuSPtr<FileHandle> &handle)
|
bool NtAsyncFileTransaction::InitWeak(const AuSPtr<IIOHandle> &handle)
|
||||||
|
{
|
||||||
|
this->wpHandle_ = handle;
|
||||||
|
this->overlap.hEvent = this->event = CreateEventW(nullptr, true, false, nullptr);
|
||||||
|
return this->overlap.hEvent != INVALID_HANDLE_VALUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool NtAsyncFileTransaction::Init(const AuSPtr<IIOHandle> &handle)
|
||||||
{
|
{
|
||||||
this->pHandle_ = handle;
|
this->pHandle_ = handle;
|
||||||
this->overlap.hEvent = this->event = CreateEventW(nullptr, true, false, nullptr);
|
this->overlap.hEvent = this->event = CreateEventW(nullptr, true, false, nullptr);
|
||||||
@ -292,8 +216,7 @@ namespace Aurora::IO::FS
|
|||||||
auto er = GetLastError();
|
auto er = GetLastError();
|
||||||
if (val)
|
if (val)
|
||||||
{
|
{
|
||||||
::SetEvent(that->event);
|
//(void)that->Complete();
|
||||||
that->DispatchCb(that->dwLastAbstractStat);
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
else if (er == ERROR_IO_PENDING)
|
else if (er == ERROR_IO_PENDING)
|
||||||
@ -309,7 +232,7 @@ namespace Aurora::IO::FS
|
|||||||
that->bHasFailed = true; // to pass completion
|
that->bHasFailed = true; // to pass completion
|
||||||
that->dwOsErrorCode = er; // to suppress actual error condition
|
that->dwOsErrorCode = er; // to suppress actual error condition
|
||||||
|
|
||||||
auto pipe = that->pNtIpcPipeImpl.lock();
|
auto pipe = AuTryLockMemoryType(that->pNtIpcPipeImpl);
|
||||||
|
|
||||||
that->DispatchCb(0);
|
that->DispatchCb(0);
|
||||||
|
|
||||||
@ -319,6 +242,7 @@ namespace Aurora::IO::FS
|
|||||||
}
|
}
|
||||||
|
|
||||||
that->pMemoryHold.reset();
|
that->pMemoryHold.reset();
|
||||||
|
that->pPin.reset();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -327,7 +251,7 @@ namespace Aurora::IO::FS
|
|||||||
that->Reset();
|
that->Reset();
|
||||||
that->dwOsErrorCode = er;
|
that->dwOsErrorCode = er;
|
||||||
that->bHasFailed = true;
|
that->bHasFailed = true;
|
||||||
SysPushErrorFIO("QoA async FIO error: {} {}", that->GetFileHandle()->path, that->dwOsErrorCode);
|
SysPushErrorFIO("QoA async FIO error: {} {}", /*that->GetFileHandle()->path*/ "", that->dwOsErrorCode);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -340,6 +264,11 @@ namespace Aurora::IO::FS
|
|||||||
auto transaction = reinterpret_cast<NtAsyncFileTransaction *>(reinterpret_cast<AuUInt8*>(lpOverlapped) - offsetof(NtAsyncFileTransaction, overlap));
|
auto transaction = reinterpret_cast<NtAsyncFileTransaction *>(reinterpret_cast<AuUInt8*>(lpOverlapped) - offsetof(NtAsyncFileTransaction, overlap));
|
||||||
auto hold = AuExchange(transaction->pPin, {});
|
auto hold = AuExchange(transaction->pPin, {});
|
||||||
|
|
||||||
|
if (!hold)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (dwErrorCode)
|
if (dwErrorCode)
|
||||||
{
|
{
|
||||||
hold->bHasFailed = true;
|
hold->bHasFailed = true;
|
||||||
@ -399,7 +328,12 @@ namespace Aurora::IO::FS
|
|||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this->pHandle_->bReadLock)
|
auto pHandle = this->GetFileHandle();
|
||||||
|
|
||||||
|
auto optRead = pHandle->GetOSReadHandleSafe();
|
||||||
|
|
||||||
|
|
||||||
|
if (!optRead)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -418,7 +352,7 @@ namespace Aurora::IO::FS
|
|||||||
this->overlap.Offset = AuBitsToLower(offset);
|
this->overlap.Offset = AuBitsToLower(offset);
|
||||||
this->overlap.OffsetHigh = AuBitsToHigher(offset);
|
this->overlap.OffsetHigh = AuBitsToHigher(offset);
|
||||||
|
|
||||||
auto ret = ::ReadFileEx(this->pHandle_->handle, memoryView->ptr, memoryView->length, &this->overlap, FileOperationCompletion);
|
auto ret = ::ReadFileEx((HANDLE)optRead.value(), memoryView->ptr, memoryView->length, &this->overlap, FileOperationCompletion);
|
||||||
return TranslateNtStatus(this, ret);
|
return TranslateNtStatus(this, ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -447,7 +381,11 @@ namespace Aurora::IO::FS
|
|||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this->pHandle_->bWriteLock)
|
auto pHandle = this->GetFileHandle();
|
||||||
|
|
||||||
|
auto optWrite = pHandle->GetOSWriteHandleSafe();
|
||||||
|
|
||||||
|
if (!optWrite)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -465,7 +403,7 @@ namespace Aurora::IO::FS
|
|||||||
this->ResetAIO();
|
this->ResetAIO();
|
||||||
this->overlap.Offset = AuBitsToLower(offset);
|
this->overlap.Offset = AuBitsToLower(offset);
|
||||||
this->overlap.OffsetHigh = AuBitsToHigher(offset);
|
this->overlap.OffsetHigh = AuBitsToHigher(offset);
|
||||||
auto ret = ::WriteFileEx(this->pHandle_->writeHandle, memoryView->ptr, memoryView->length, &this->overlap, FileOperationCompletion);
|
auto ret = ::WriteFileEx((HANDLE)optWrite.value(), memoryView->ptr, memoryView->length, &this->overlap, FileOperationCompletion);
|
||||||
return TranslateNtStatus(this, ret);
|
return TranslateNtStatus(this, ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -493,14 +431,22 @@ namespace Aurora::IO::FS
|
|||||||
{
|
{
|
||||||
this->isIrredeemable_ = true;
|
this->isIrredeemable_ = true;
|
||||||
this->bHasFailed = true;
|
this->bHasFailed = true;
|
||||||
if (pCancelIoEx)
|
|
||||||
|
auto hOptSafe = this->GetFileHandle()->GetOSReadHandleSafe();
|
||||||
|
if (hOptSafe)
|
||||||
{
|
{
|
||||||
pCancelIoEx(this->pHandle_->handle, &this->overlap);
|
auto hHandle = (HANDLE)hOptSafe.Value();
|
||||||
}
|
|
||||||
else
|
if (pCancelIoEx)
|
||||||
{
|
{
|
||||||
::CancelIo(this->pHandle_->handle);
|
pCancelIoEx(hHandle, &this->overlap);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
::CancelIo(hHandle);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
::SetEvent(this->event);
|
::SetEvent(this->event);
|
||||||
this->dwOsErrorCode = ERROR_ABANDONED_WAIT_0;
|
this->dwOsErrorCode = ERROR_ABANDONED_WAIT_0;
|
||||||
}
|
}
|
||||||
@ -540,13 +486,20 @@ namespace Aurora::IO::FS
|
|||||||
|
|
||||||
if (!completeRoutine)
|
if (!completeRoutine)
|
||||||
{
|
{
|
||||||
if (::GetOverlappedResult(this->pHandle_->handle,
|
auto hOptSafe = this->GetFileHandle()->GetOSReadHandleSafe();
|
||||||
&this->overlap,
|
if (hOptSafe)
|
||||||
&read,
|
|
||||||
false) && (read || bForce))
|
|
||||||
{
|
{
|
||||||
DispatchCb(read);
|
auto hHandle = (HANDLE)hOptSafe.Value();
|
||||||
return true;
|
|
||||||
|
if (::GetOverlappedResult(hHandle,
|
||||||
|
&this->overlap,
|
||||||
|
&read,
|
||||||
|
false) && (read || bForce))
|
||||||
|
{
|
||||||
|
SetEvent(this->overlap.hEvent);
|
||||||
|
DispatchCb(read);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -572,7 +525,7 @@ namespace Aurora::IO::FS
|
|||||||
}
|
}
|
||||||
|
|
||||||
return bool(this->dwLastBytes) ||
|
return bool(this->dwLastBytes) ||
|
||||||
this->Failed();
|
this->bHasFailed;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool NtAsyncFileTransaction::Complete()
|
bool NtAsyncFileTransaction::Complete()
|
||||||
@ -616,9 +569,9 @@ namespace Aurora::IO::FS
|
|||||||
return this->event;
|
return this->event;
|
||||||
}
|
}
|
||||||
|
|
||||||
AuSPtr<FileHandle> NtAsyncFileTransaction::GetFileHandle()
|
AuSPtr<IIOHandle> NtAsyncFileTransaction::GetFileHandle()
|
||||||
{
|
{
|
||||||
return this->pHandle_;
|
return this->pHandle_ ? this->pHandle_ : AuTryLockMemoryType(this->wpHandle_);
|
||||||
}
|
}
|
||||||
|
|
||||||
AuSPtr<AuLoop::ILoopSource> NtAsyncFileTransaction::NewLoopSource()
|
AuSPtr<AuLoop::ILoopSource> NtAsyncFileTransaction::NewLoopSource()
|
||||||
@ -628,36 +581,34 @@ namespace Aurora::IO::FS
|
|||||||
|
|
||||||
AUKN_SYM IAsyncFileStream *OpenAsyncNew(const AuString &path, EFileOpenMode openMode, bool directIO, EFileAdvisoryLockLevel lock)
|
AUKN_SYM IAsyncFileStream *OpenAsyncNew(const AuString &path, EFileOpenMode openMode, bool directIO, EFileAdvisoryLockLevel lock)
|
||||||
{
|
{
|
||||||
AuSPtr<FileHandle> fileHandle;
|
auto pHandle = AuIO::IOHandleShared();
|
||||||
NtAsyncFileStream *stream;
|
if (!pHandle)
|
||||||
|
|
||||||
if (path.empty())
|
|
||||||
{
|
{
|
||||||
SysPushErrorParam("Empty path");
|
SysPushErrorMemory();
|
||||||
return {};
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!EFileOpenModeIsValid(openMode))
|
AuIO::IIOHandle::HandleCreate createhandle(path);
|
||||||
|
createhandle.eAdvisoryLevel = lock;
|
||||||
|
createhandle.eMode = openMode;
|
||||||
|
createhandle.bFailIfNonEmptyFile = false;
|
||||||
|
createhandle.bDirectIOMode = directIO;
|
||||||
|
createhandle.bAsyncHandle = true;
|
||||||
|
|
||||||
|
if (!pHandle->InitFromPath(createhandle))
|
||||||
{
|
{
|
||||||
SysPushErrorParam("Invalid open mode");
|
return nullptr;
|
||||||
return {};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fileHandle = AuMakeShared<FileHandle>();
|
auto pStream = _new NtAsyncFileStream();
|
||||||
if (!fileHandle->Init(path, openMode, directIO, lock))
|
if (!pStream)
|
||||||
{
|
{
|
||||||
return {};
|
SysPushErrorMemory();
|
||||||
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
stream = _new NtAsyncFileStream();
|
pStream->Init(pHandle);
|
||||||
if (!stream)
|
return pStream;
|
||||||
{
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
|
|
||||||
stream->Init(fileHandle);
|
|
||||||
|
|
||||||
return stream;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
AUKN_SYM void OpenAsyncRelease(IAsyncFileStream *handle)
|
AUKN_SYM void OpenAsyncRelease(IAsyncFileStream *handle)
|
||||||
|
@ -14,22 +14,6 @@ namespace Aurora::IO::IPC
|
|||||||
|
|
||||||
namespace Aurora::IO::FS
|
namespace Aurora::IO::FS
|
||||||
{
|
{
|
||||||
struct FileHandle
|
|
||||||
{
|
|
||||||
~FileHandle();
|
|
||||||
|
|
||||||
bool Init(const AuString &path, EFileOpenMode openMode, bool directIO, EFileAdvisoryLockLevel lock);
|
|
||||||
void Init(HANDLE read, HANDLE write);
|
|
||||||
|
|
||||||
HANDLE handle {INVALID_HANDLE_VALUE}, writeHandle {INVALID_HANDLE_VALUE};
|
|
||||||
AuString path;
|
|
||||||
bool readOnly;
|
|
||||||
bool directIO;
|
|
||||||
bool bNoOwns { false };
|
|
||||||
bool bWriteLock { false };
|
|
||||||
bool bReadLock { false };
|
|
||||||
};
|
|
||||||
|
|
||||||
struct NtAsyncFileStream : IAsyncFileStream
|
struct NtAsyncFileStream : IAsyncFileStream
|
||||||
{
|
{
|
||||||
AuSPtr<IAsyncTransaction> NewTransaction() override;
|
AuSPtr<IAsyncTransaction> NewTransaction() override;
|
||||||
@ -38,19 +22,20 @@ namespace Aurora::IO::FS
|
|||||||
bool BlockingRead(AuUInt64 offset, const Memory::MemoryViewStreamWrite ¶meters) override;
|
bool BlockingRead(AuUInt64 offset, const Memory::MemoryViewStreamWrite ¶meters) override;
|
||||||
bool BlockingWrite(AuUInt64 offset, const Memory::MemoryViewStreamRead ¶meters) override;
|
bool BlockingWrite(AuUInt64 offset, const Memory::MemoryViewStreamRead ¶meters) override;
|
||||||
|
|
||||||
void Init(const AuSPtr<FileHandle> &handle);
|
void Init(const AuSPtr<IIOHandle> &pHandle);
|
||||||
|
|
||||||
AuSPtr<FileHandle> GetHandle();
|
AuSPtr<IIOHandle> GetHandle();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
AuSPtr<FileHandle> handle_;
|
AuSPtr<IIOHandle> pHandle_;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct NtAsyncFileTransaction : IAsyncTransaction, AuEnableSharedFromThis<NtAsyncFileTransaction>
|
struct NtAsyncFileTransaction : IAsyncTransaction, AuEnableSharedFromThis<NtAsyncFileTransaction>
|
||||||
{
|
{
|
||||||
~NtAsyncFileTransaction();
|
~NtAsyncFileTransaction();
|
||||||
|
|
||||||
bool Init(const AuSPtr<FileHandle> &handle);
|
bool Init(const AuSPtr<IIOHandle> &handle);
|
||||||
|
bool InitWeak(const AuSPtr<IIOHandle> &handle);
|
||||||
void ResetAIO();
|
void ResetAIO();
|
||||||
|
|
||||||
bool StartRead(AuUInt64 offset, const AuSPtr<AuMemoryViewWrite> &memoryView) override;
|
bool StartRead(AuUInt64 offset, const AuSPtr<AuMemoryViewWrite> &memoryView) override;
|
||||||
@ -78,7 +63,7 @@ namespace Aurora::IO::FS
|
|||||||
|
|
||||||
void DispatchCb(AuUInt32 len);
|
void DispatchCb(AuUInt32 len);
|
||||||
HANDLE GetHandle();
|
HANDLE GetHandle();
|
||||||
AuSPtr<FileHandle> GetFileHandle();
|
AuSPtr<IIOHandle> GetFileHandle();
|
||||||
|
|
||||||
OVERLAPPED overlap {};
|
OVERLAPPED overlap {};
|
||||||
HANDLE event = INVALID_HANDLE_VALUE;
|
HANDLE event = INVALID_HANDLE_VALUE;
|
||||||
@ -94,7 +79,8 @@ namespace Aurora::IO::FS
|
|||||||
AuSPtr<void> pMemoryHold;
|
AuSPtr<void> pMemoryHold;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
AuSPtr<FileHandle> pHandle_;
|
AuSPtr<IIOHandle> pHandle_;
|
||||||
|
AuWPtr<IIOHandle> wpHandle_;
|
||||||
AuSPtr<IAsyncFinishedSubscriber> pSub_;
|
AuSPtr<IAsyncFinishedSubscriber> pSub_;
|
||||||
};
|
};
|
||||||
}
|
}
|
@ -14,17 +14,16 @@
|
|||||||
|
|
||||||
namespace Aurora::IO::FS
|
namespace Aurora::IO::FS
|
||||||
{
|
{
|
||||||
static const AuUInt64 kFileCopyBlock = 0xFFFF; // 64KiB, 1k iterations to max out 64MB/s disk, 2k iteration to make out 128MB/s disk, is this number still way too low? cpu go brr
|
static const AuUInt64 kFileCopyBlock = 0xFFFF * 128;
|
||||||
|
|
||||||
WinFileStream::~WinFileStream()
|
WinFileStream::~WinFileStream()
|
||||||
{
|
{
|
||||||
Close();
|
Close();
|
||||||
}
|
}
|
||||||
|
|
||||||
void WinFileStream::Init(HANDLE handle, const AuString &path)
|
void WinFileStream::Init(AuSPtr<IIOHandle> pHandle)
|
||||||
{
|
{
|
||||||
this->handle_ = handle;
|
this->pHandle_ = pHandle;
|
||||||
this->path_ = path;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
AuUInt64 WinFileStream::GetOffset()
|
AuUInt64 WinFileStream::GetOffset()
|
||||||
@ -32,16 +31,20 @@ namespace Aurora::IO::FS
|
|||||||
LARGE_INTEGER distance {};
|
LARGE_INTEGER distance {};
|
||||||
LARGE_INTEGER pos {};
|
LARGE_INTEGER pos {};
|
||||||
|
|
||||||
if (this->handle_ == INVALID_HANDLE_VALUE)
|
auto hHandle = this->GetHandle();
|
||||||
|
|
||||||
|
if (hHandle == INVALID_HANDLE_VALUE)
|
||||||
{
|
{
|
||||||
SysPushErrorUninitialized();
|
SysPushErrorUninitialized();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (SetFilePointerEx(this->handle_, distance, &pos, FILE_CURRENT) == INVALID_SET_FILE_POINTER)
|
if (::SetFilePointerEx(hHandle,
|
||||||
|
distance,
|
||||||
|
&pos,
|
||||||
|
FILE_CURRENT) == INVALID_SET_FILE_POINTER)
|
||||||
{
|
{
|
||||||
AuLogWarn("SetFilePointerEx IO Error: 0x{:x}, {}", GetLastError(), path_);
|
SysPushErrorIO("SetFilePointerEx IO Error: 0x{:x}, {}", GetLastError(), this->pHandle_ ? this->pHandle_->GetPath() : "");
|
||||||
SysPushErrorIO();
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -53,7 +56,9 @@ namespace Aurora::IO::FS
|
|||||||
LARGE_INTEGER distance {};
|
LARGE_INTEGER distance {};
|
||||||
LARGE_INTEGER pos {};
|
LARGE_INTEGER pos {};
|
||||||
|
|
||||||
if (this->handle_ == INVALID_HANDLE_VALUE)
|
auto hHandle = this->GetHandle();
|
||||||
|
|
||||||
|
if (hHandle == INVALID_HANDLE_VALUE)
|
||||||
{
|
{
|
||||||
SysPushErrorUninitialized();
|
SysPushErrorUninitialized();
|
||||||
return false;
|
return false;
|
||||||
@ -61,10 +66,9 @@ namespace Aurora::IO::FS
|
|||||||
|
|
||||||
distance.QuadPart = offset;
|
distance.QuadPart = offset;
|
||||||
|
|
||||||
if (SetFilePointerEx(this->handle_, distance, &pos, FILE_BEGIN) == INVALID_SET_FILE_POINTER)
|
if (::SetFilePointerEx(hHandle, distance, &pos, FILE_BEGIN) == INVALID_SET_FILE_POINTER)
|
||||||
{
|
{
|
||||||
AuLogWarn("SetFilePointerEx IO Error: 0x{:x}, {}", GetLastError(), path_);
|
SysPushErrorIO("SetFilePointerEx IO Error: 0x{:x}, {}", GetLastError(), this->pHandle_ ? this->pHandle_->GetPath() : "");
|
||||||
SysPushErrorIO();
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -74,14 +78,16 @@ namespace Aurora::IO::FS
|
|||||||
AuUInt64 WinFileStream::GetLength()
|
AuUInt64 WinFileStream::GetLength()
|
||||||
{
|
{
|
||||||
LARGE_INTEGER length;
|
LARGE_INTEGER length;
|
||||||
|
|
||||||
|
auto hHandle = this->GetHandle();
|
||||||
|
|
||||||
if (handle_ == INVALID_HANDLE_VALUE)
|
if (hHandle == INVALID_HANDLE_VALUE)
|
||||||
{
|
{
|
||||||
SysPushErrorUninitialized();
|
SysPushErrorUninitialized();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!GetFileSizeEx(this->handle_, &length))
|
if (!::GetFileSizeEx(hHandle, &length))
|
||||||
{
|
{
|
||||||
SysPushErrorIO();
|
SysPushErrorIO();
|
||||||
return 0;
|
return 0;
|
||||||
@ -92,113 +98,218 @@ namespace Aurora::IO::FS
|
|||||||
|
|
||||||
bool WinFileStream::Read(const Memory::MemoryViewStreamWrite ¶meters)
|
bool WinFileStream::Read(const Memory::MemoryViewStreamWrite ¶meters)
|
||||||
{
|
{
|
||||||
if (this->handle_ == INVALID_HANDLE_VALUE)
|
auto hHandle = this->GetHandle();
|
||||||
|
HANDLE hEventHandle { INVALID_HANDLE_VALUE };
|
||||||
|
|
||||||
|
if (hHandle == INVALID_HANDLE_VALUE)
|
||||||
{
|
{
|
||||||
SysPushErrorUninitialized();
|
SysPushErrorUninitialized();
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
auto length = parameters.length;
|
bool bIsAsync = this->pHandle_->IsAsync();
|
||||||
|
|
||||||
|
if (bIsAsync)
|
||||||
|
{
|
||||||
|
hEventHandle = ::CreateEventA(nullptr, false, false, nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
parameters.outVariable = 0;
|
parameters.outVariable = 0;
|
||||||
AuUInt64 offset {0};
|
|
||||||
while (length)
|
AuUInt64 uLength = parameters.length;
|
||||||
|
AuUInt64 uOffset {};
|
||||||
|
while (uLength)
|
||||||
{
|
{
|
||||||
DWORD read;
|
DWORD read;
|
||||||
|
|
||||||
int blockSize = AuMin(AuUInt(kFileCopyBlock), length);
|
auto blockSize = AuMin(AuUInt(kFileCopyBlock), uLength);
|
||||||
|
|
||||||
if (!::ReadFile(this->handle_, reinterpret_cast<char *>(parameters.ptr) + offset, blockSize, &read, NULL))
|
if (this->pHandle_->IsAsync())
|
||||||
{
|
{
|
||||||
AuLogWarn("ReadFile IO Error: 0x{:x}, {}", GetLastError(), path_);
|
OVERLAPPED overlapped {};
|
||||||
SysPushErrorIO();
|
overlapped.hEvent = hEventHandle;
|
||||||
return false;
|
|
||||||
|
if (!::ReadFile(hHandle,
|
||||||
|
reinterpret_cast<char *>(parameters.ptr) + uOffset,
|
||||||
|
blockSize,
|
||||||
|
NULL,
|
||||||
|
&overlapped) &&
|
||||||
|
::GetLastError() != ERROR_IO_PENDING)
|
||||||
|
{
|
||||||
|
SysPushErrorIO("ReadFile IO Error: 0x{:x}, {}", GetLastError(), this->pHandle_ ? this->pHandle_->GetPath() : "");
|
||||||
|
AuWin32CloseHandle(hEventHandle);
|
||||||
|
parameters.outVariable = uOffset;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
::WaitForSingleObject(hEventHandle, 0);
|
||||||
|
|
||||||
|
if (!::GetOverlappedResult(hHandle, &overlapped, &read, true))
|
||||||
|
{
|
||||||
|
AuWin32CloseHandle(hEventHandle);
|
||||||
|
parameters.outVariable = uOffset;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
::CloseHandle(hEventHandle);
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (!::ReadFile(hHandle,
|
||||||
|
reinterpret_cast<char *>(parameters.ptr) + uOffset,
|
||||||
|
blockSize,
|
||||||
|
&read,
|
||||||
|
NULL))
|
||||||
|
{
|
||||||
|
SysPushErrorIO("ReadFile IO Error: 0x{:x}, {}", GetLastError(), this->pHandle_ ? this->pHandle_->GetPath() : "");
|
||||||
|
AuWin32CloseHandle(hEventHandle);
|
||||||
|
parameters.outVariable = uOffset;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (read == 0)
|
if (read == 0)
|
||||||
{
|
{
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
offset += read;
|
uOffset += read;
|
||||||
length -= read;
|
uLength -= read;
|
||||||
}
|
}
|
||||||
|
|
||||||
parameters.outVariable = offset;
|
AuWin32CloseHandle(hEventHandle);
|
||||||
|
parameters.outVariable = uOffset;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool WinFileStream::Write(const Memory::MemoryViewStreamRead ¶meters)
|
bool WinFileStream::Write(const Memory::MemoryViewStreamRead ¶meters)
|
||||||
{
|
{
|
||||||
if (this->handle_ == INVALID_HANDLE_VALUE)
|
auto hHandle = this->GetHandle();
|
||||||
|
HANDLE hEventHandle { INVALID_HANDLE_VALUE };
|
||||||
|
|
||||||
|
if (hHandle == INVALID_HANDLE_VALUE)
|
||||||
{
|
{
|
||||||
SysPushErrorUninitialized();
|
SysPushErrorUninitialized();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto length = parameters.length;
|
bool bIsAsync = this->pHandle_->IsAsync();
|
||||||
|
|
||||||
|
if (bIsAsync)
|
||||||
|
{
|
||||||
|
hEventHandle = ::CreateEventA(nullptr, false, false, nullptr);
|
||||||
|
}
|
||||||
parameters.outVariable = 0;
|
parameters.outVariable = 0;
|
||||||
AuUInt offset {0};
|
|
||||||
while (length)
|
AuUInt64 uLength = parameters.length;
|
||||||
|
AuUInt64 uOffset {};
|
||||||
|
while (uLength)
|
||||||
{
|
{
|
||||||
DWORD written;
|
DWORD written;
|
||||||
|
|
||||||
int blockSize = AuMin(AuUInt(kFileCopyBlock), length);
|
auto uBlockSize = AuMin(AuUInt(kFileCopyBlock), uLength);
|
||||||
|
|
||||||
if (!::WriteFile(this->handle_, reinterpret_cast<const char *>(parameters.ptr) + offset, blockSize, &written, NULL))
|
if (this->pHandle_->IsAsync())
|
||||||
{
|
{
|
||||||
SysPushErrorIO("WriteFileEx IO Error: 0x{:x}, {}", GetLastError(), this->path_);
|
OVERLAPPED overlapped {};
|
||||||
return false;
|
overlapped.hEvent = hEventHandle;
|
||||||
|
|
||||||
|
if (!::WriteFile(hHandle,
|
||||||
|
reinterpret_cast<const char *>(parameters.ptr) + uOffset,
|
||||||
|
uBlockSize,
|
||||||
|
NULL,
|
||||||
|
&overlapped) &&
|
||||||
|
::GetLastError() != ERROR_IO_PENDING)
|
||||||
|
{
|
||||||
|
SysPushErrorIO("WriteFile IO Error: 0x{:x}, {}", GetLastError(), this->pHandle_ ? this->pHandle_->GetPath() : "");
|
||||||
|
AuWin32CloseHandle(hEventHandle);
|
||||||
|
parameters.outVariable = uOffset;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
::WaitForSingleObject(hEventHandle, 0);
|
||||||
|
|
||||||
|
if (!::GetOverlappedResult(hHandle, &overlapped, &written, true))
|
||||||
|
{
|
||||||
|
AuWin32CloseHandle(hEventHandle);
|
||||||
|
parameters.outVariable = uOffset;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
::CloseHandle(hEventHandle);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (!::WriteFile(hHandle, reinterpret_cast<const char *>(parameters.ptr) + uOffset, uBlockSize, &written, NULL))
|
||||||
|
{
|
||||||
|
SysPushErrorIO("WriteFile IO Error: 0x{:x}, {}", GetLastError(), this->pHandle_ ? this->pHandle_->GetPath() : "");
|
||||||
|
AuWin32CloseHandle(hEventHandle);
|
||||||
|
parameters.outVariable = uOffset;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!written)
|
if (!written)
|
||||||
{
|
{
|
||||||
SysPushErrorIO();
|
SysPushErrorIO();
|
||||||
parameters.outVariable = offset;
|
parameters.outVariable = uOffset;
|
||||||
|
|
||||||
|
AuWin32CloseHandle(hEventHandle);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
offset += written;
|
uOffset += written;
|
||||||
length -= written;
|
uLength -= written;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!offset)
|
AuWin32CloseHandle(hEventHandle);
|
||||||
|
|
||||||
|
if (!uOffset)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
parameters.outVariable = offset;
|
parameters.outVariable = uOffset;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void WinFileStream::WriteEoS()
|
void WinFileStream::WriteEoS()
|
||||||
{
|
{
|
||||||
if (this->handle_ == INVALID_HANDLE_VALUE)
|
auto hHandle = this->GetHandle();
|
||||||
|
|
||||||
|
if (hHandle == INVALID_HANDLE_VALUE)
|
||||||
{
|
{
|
||||||
SysPushErrorUninitialized();
|
SysPushErrorUninitialized();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
SetEndOfFile(this->handle_);
|
SetEndOfFile(hHandle);
|
||||||
}
|
}
|
||||||
|
|
||||||
void WinFileStream::Close()
|
void WinFileStream::Close()
|
||||||
{
|
{
|
||||||
if ((this->handle_ != INVALID_HANDLE_VALUE) &&
|
auto hHandle = this->GetHandle();
|
||||||
|
|
||||||
|
if ((hHandle != INVALID_HANDLE_VALUE) &&
|
||||||
(this->bShouldDelete))
|
(this->bShouldDelete))
|
||||||
{
|
{
|
||||||
FILE_DISPOSITION_INFO rm {};
|
FILE_DISPOSITION_INFO rm {};
|
||||||
rm.DeleteFile = true;
|
rm.DeleteFile = true;
|
||||||
if (!(pSetFileInformationByHandle && pSetFileInformationByHandle(this->handle_, _FILE_INFO_BY_HANDLE_CLASS::FileDispositionInfo, &rm, sizeof(rm))))
|
if (!(pSetFileInformationByHandle &&
|
||||||
|
pSetFileInformationByHandle(hHandle, _FILE_INFO_BY_HANDLE_CLASS::FileDispositionInfo, &rm, sizeof(rm))))
|
||||||
{
|
{
|
||||||
SysPushErrorIO("Couldn't delete temporary file {}", this->path_);
|
SysPushErrorIO("Couldn't delete temporary file {}", this->pHandle_ ? this->pHandle_->GetPath() : "");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
AuWin32CloseHandle(this->handle_);
|
|
||||||
|
AuResetMember(this->pHandle_);
|
||||||
}
|
}
|
||||||
|
|
||||||
void WinFileStream::Flush()
|
void WinFileStream::Flush()
|
||||||
{
|
{
|
||||||
FlushFileBuffers(this->handle_);
|
auto hHandle = this->GetHandle();
|
||||||
|
|
||||||
|
::FlushFileBuffers(hHandle);
|
||||||
}
|
}
|
||||||
|
|
||||||
void WinFileStream::MakeTemporary()
|
void WinFileStream::MakeTemporary()
|
||||||
@ -208,104 +319,57 @@ namespace Aurora::IO::FS
|
|||||||
|
|
||||||
HANDLE WinFileStream::GetHandle()
|
HANDLE WinFileStream::GetHandle()
|
||||||
{
|
{
|
||||||
return this->handle_;
|
return this->pHandle_ ?
|
||||||
|
(HANDLE)this->pHandle_->GetOSWriteHandleSafe().ValueOr(this->pHandle_->GetOSReadHandleSafe().ValueOr((AuUInt)INVALID_HANDLE_VALUE)) :
|
||||||
|
INVALID_HANDLE_VALUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static IFileStream *OpenNewEx(const AuString &path, EFileOpenMode openMode, EFileAdvisoryLockLevel lock, bool bCheck)
|
AUKN_SYM AuSPtr<IFileStream> OpenBlockingFileStreamFromHandle(AuSPtr<IIOHandle> pIOHandle)
|
||||||
|
{
|
||||||
|
auto pStream = AuMakeShared<WinFileStream>();
|
||||||
|
if (!pStream)
|
||||||
|
{
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
pStream->Init(pIOHandle);
|
||||||
|
return pStream;
|
||||||
|
}
|
||||||
|
|
||||||
|
static IFileStream *OpenNewEx(const AuString &path,
|
||||||
|
EFileOpenMode openMode,
|
||||||
|
EFileAdvisoryLockLevel lock,
|
||||||
|
bool bCheck)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
auto pathex = NormalizePathRet(path);
|
auto pHandle = AuIO::IOHandleShared();
|
||||||
if (pathex.empty())
|
if (!pHandle)
|
||||||
|
{
|
||||||
|
SysPushErrorMemory();
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
AuIO::IIOHandle::HandleCreate createhandle(path);
|
||||||
|
createhandle.eAdvisoryLevel = lock;
|
||||||
|
createhandle.eMode = openMode;
|
||||||
|
createhandle.bFailIfNonEmptyFile = bCheck;
|
||||||
|
createhandle.bDirectIOMode = false;
|
||||||
|
createhandle.bAsyncHandle = false;
|
||||||
|
|
||||||
|
if (!pHandle->InitFromPath(createhandle))
|
||||||
{
|
{
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto win32Path = Locale::ConvertFromUTF8(pathex);
|
auto pStream = _new WinFileStream();
|
||||||
if (win32Path.empty())
|
if (!pStream)
|
||||||
{
|
{
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
HANDLE fileHandle;
|
pStream->Init(pHandle);
|
||||||
|
return pStream;
|
||||||
fileHandle = INVALID_HANDLE_VALUE;
|
|
||||||
|
|
||||||
auto dwShare = NtLockAdvisoryToShare(lock);
|
|
||||||
|
|
||||||
switch (openMode)
|
|
||||||
{
|
|
||||||
case EFileOpenMode::eRead:
|
|
||||||
{
|
|
||||||
fileHandle = CreateFileW(win32Path.c_str(), GENERIC_READ, dwShare, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case EFileOpenMode::eReadWrite:
|
|
||||||
{
|
|
||||||
CreateDirectories(pathex, true);
|
|
||||||
|
|
||||||
if (bCheck)
|
|
||||||
{
|
|
||||||
fileHandle = ::CreateFileW(win32Path.c_str(),
|
|
||||||
GENERIC_WRITE | GENERIC_READ | DELETE,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
CREATE_NEW,
|
|
||||||
FILE_ATTRIBUTE_NORMAL,
|
|
||||||
NULL);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
fileHandle = CreateFileW(win32Path.c_str(), GENERIC_WRITE | GENERIC_READ | DELETE, dwShare, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
|
|
||||||
if (fileHandle == INVALID_HANDLE_VALUE)
|
|
||||||
{
|
|
||||||
fileHandle = CreateFileW(win32Path.c_str(), GENERIC_WRITE | GENERIC_READ | DELETE, dwShare, NULL, CREATE_NEW, FILE_ATTRIBUTE_NORMAL, NULL);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case EFileOpenMode::eWrite:
|
|
||||||
{
|
|
||||||
CreateDirectories(pathex, true);
|
|
||||||
|
|
||||||
if (bCheck)
|
|
||||||
{
|
|
||||||
fileHandle = ::CreateFileW(win32Path.c_str(),
|
|
||||||
GENERIC_WRITE | DELETE,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
CREATE_NEW,
|
|
||||||
FILE_ATTRIBUTE_NORMAL,
|
|
||||||
NULL);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
fileHandle = CreateFileW(win32Path.c_str(), GENERIC_WRITE | FILE_READ_ATTRIBUTES | DELETE, dwShare, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
|
|
||||||
if (fileHandle == INVALID_HANDLE_VALUE)
|
|
||||||
{
|
|
||||||
fileHandle = CreateFileW(win32Path.c_str(), GENERIC_WRITE | DELETE, dwShare, NULL, CREATE_NEW, FILE_ATTRIBUTE_NORMAL, NULL);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (fileHandle == INVALID_HANDLE_VALUE)
|
|
||||||
{
|
|
||||||
SysPushErrorIO("Invalid filepath, couldn't open: {}", path);
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto stream = _new WinFileStream();
|
|
||||||
if (!stream)
|
|
||||||
{
|
|
||||||
CloseHandle(fileHandle);
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
stream->Init(fileHandle, pathex);
|
|
||||||
return stream;
|
|
||||||
}
|
}
|
||||||
catch (...)
|
catch (...)
|
||||||
{
|
{
|
||||||
|
@ -15,7 +15,7 @@ namespace Aurora::IO::FS
|
|||||||
{
|
{
|
||||||
~WinFileStream();
|
~WinFileStream();
|
||||||
|
|
||||||
void Init(HANDLE handle, const AuString &path);
|
void Init(AuSPtr<IIOHandle> pHandle);
|
||||||
|
|
||||||
AuUInt64 GetOffset() override;
|
AuUInt64 GetOffset() override;
|
||||||
bool SetOffset(AuUInt64 offset) override;
|
bool SetOffset(AuUInt64 offset) override;
|
||||||
@ -28,11 +28,11 @@ namespace Aurora::IO::FS
|
|||||||
void MakeTemporary() override;
|
void MakeTemporary() override;
|
||||||
|
|
||||||
HANDLE GetHandle();
|
HANDLE GetHandle();
|
||||||
private:
|
|
||||||
|
|
||||||
|
private:
|
||||||
|
AuSPtr<IIOHandle> pHandle_;
|
||||||
bool bShouldDelete {};
|
bool bShouldDelete {};
|
||||||
HANDLE handle_ = INVALID_HANDLE_VALUE;
|
HANDLE hEventHandle_ { INVALID_HANDLE_VALUE };
|
||||||
AuString path_;
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
@ -88,12 +88,15 @@ namespace Aurora::IO::IPC
|
|||||||
if (serverHandle != INVALID_HANDLE_VALUE)
|
if (serverHandle != INVALID_HANDLE_VALUE)
|
||||||
{
|
{
|
||||||
this->hasClient_ = Loop::NewLSEvent(false, false, true);
|
this->hasClient_ = Loop::NewLSEvent(false, false, true);
|
||||||
|
SysAssert(this->hasClient_);
|
||||||
}
|
}
|
||||||
|
|
||||||
this->fsHandle_ = AuMakeShared<IO::FS::FileHandle>();
|
this->fsHandle_ = AuIO::IOHandleShared();
|
||||||
this->fsStream_ = AuMakeShared<IO::FS::NtAsyncFileStream>();
|
SysAssert(this->fsHandle_);
|
||||||
|
|
||||||
this->fsHandle_->Init(this->GetPipeHandle(), this->GetPipeHandle());
|
this->fsStream_ = AuMakeSharedPanic<IO::FS::NtAsyncFileStream>();
|
||||||
|
|
||||||
|
this->fsHandle_->InitFromMove((AuUInt)this->GetPipeHandle());
|
||||||
this->fsStream_->Init(this->fsHandle_);
|
this->fsStream_->Init(this->fsHandle_);
|
||||||
|
|
||||||
TryConnect();
|
TryConnect();
|
||||||
|
@ -49,7 +49,7 @@ namespace Aurora::IO::IPC
|
|||||||
private:
|
private:
|
||||||
HANDLE serverHandle_ {INVALID_HANDLE_VALUE};
|
HANDLE serverHandle_ {INVALID_HANDLE_VALUE};
|
||||||
IPCHandle ipcHandle_;
|
IPCHandle ipcHandle_;
|
||||||
AuSPtr<IO::FS::FileHandle> fsHandle_;
|
AuSPtr<IO::IIOHandle> fsHandle_;
|
||||||
AuSPtr<IO::FS::NtAsyncFileStream> fsStream_;
|
AuSPtr<IO::FS::NtAsyncFileStream> fsStream_;
|
||||||
AuSPtr<IPCHasConnectionEvent> lshasConnection_;
|
AuSPtr<IPCHasConnectionEvent> lshasConnection_;
|
||||||
bool bFirstTime {true};
|
bool bFirstTime {true};
|
||||||
|
@ -14,6 +14,8 @@
|
|||||||
#include "AuNetSocketServer.hpp"
|
#include "AuNetSocketServer.hpp"
|
||||||
#include "AuNetInterface.hpp"
|
#include "AuNetInterface.hpp"
|
||||||
|
|
||||||
|
#include "../AuIOHandle.hpp"
|
||||||
|
|
||||||
#if defined(AURORA_IS_MODERNNT_DERIVED)
|
#if defined(AURORA_IS_MODERNNT_DERIVED)
|
||||||
#include "AuNetStream.NT.hpp"
|
#include "AuNetStream.NT.hpp"
|
||||||
#endif
|
#endif
|
||||||
@ -40,7 +42,7 @@ namespace Aurora::IO::Net
|
|||||||
{
|
{
|
||||||
this->pWorker_->AddSocket(this);
|
this->pWorker_->AddSocket(this);
|
||||||
|
|
||||||
this->osHandleOwner_ = AuMakeShared<AuFS::FileHandle>();
|
this->osHandleOwner_ = AuIO::IOHandleShared();
|
||||||
if (!this->osHandle_)
|
if (!this->osHandle_)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
@ -48,10 +50,11 @@ namespace Aurora::IO::Net
|
|||||||
|
|
||||||
|
|
||||||
#if defined(AURORA_IS_MODERNNT_DERIVED)
|
#if defined(AURORA_IS_MODERNNT_DERIVED)
|
||||||
//this->osHandleOwner_->Init((HANDLE)this->osHandle_, (HANDLE)this->osHandle_);
|
//this->osHandleOwner_->InitFromPairMove((HANDLE)this->osHandle_, (HANDLE)this->osHandle_);
|
||||||
#else
|
#else
|
||||||
this->osHandleOwner_->Init((int)this->osHandle_, (int)this->osHandle_);
|
this->osHandleOwner_->InitFromPairMove((int)this->osHandle_, (int)this->osHandle_);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
SocketBase::SocketBase(struct NetInterface *pInterface,
|
SocketBase::SocketBase(struct NetInterface *pInterface,
|
||||||
@ -65,7 +68,7 @@ namespace Aurora::IO::Net
|
|||||||
pSocketDriver_(pSocketDriver),
|
pSocketDriver_(pSocketDriver),
|
||||||
remoteEndpoint_(endpoint)
|
remoteEndpoint_(endpoint)
|
||||||
{
|
{
|
||||||
this->osHandleOwner_ = AuMakeShared<AuFS::FileHandle>();
|
this->osHandleOwner_ = AuIO::IOHandleShared();
|
||||||
if (!this->osHandle_)
|
if (!this->osHandle_)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
@ -102,7 +105,8 @@ namespace Aurora::IO::Net
|
|||||||
this->connectMany_.protocol = eProtocol;
|
this->connectMany_.protocol = eProtocol;
|
||||||
}
|
}
|
||||||
|
|
||||||
this->osHandleOwner_ = AuMakeShared<AuFS::FileHandle>();
|
this->osHandleOwner_ = AuIO::IOHandleShared();
|
||||||
|
|
||||||
if (!this->osHandle_)
|
if (!this->osHandle_)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
@ -126,7 +130,8 @@ namespace Aurora::IO::Net
|
|||||||
{
|
{
|
||||||
this->connectMany_.pDriver.reset();
|
this->connectMany_.pDriver.reset();
|
||||||
|
|
||||||
this->osHandleOwner_ = AuMakeShared<AuFS::FileHandle>();
|
this->osHandleOwner_ = AuIO::IOHandleShared();
|
||||||
|
|
||||||
if (!this->osHandle_)
|
if (!this->osHandle_)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
@ -490,7 +495,7 @@ namespace Aurora::IO::Net
|
|||||||
{
|
{
|
||||||
if (this->osHandleOwner_)
|
if (this->osHandleOwner_)
|
||||||
{
|
{
|
||||||
this->osHandleOwner_->bWriteLock = true;
|
AuStaticCast<AFileHandle>(this->osHandleOwner_)->uOSWriteHandle.Reset();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -137,7 +137,7 @@ namespace Aurora::IO::Net
|
|||||||
NetInterface *pInterface_;
|
NetInterface *pInterface_;
|
||||||
SocketChannel socketChannel_;
|
SocketChannel socketChannel_;
|
||||||
AuSPtr<ISocketDriver> pSocketDriver_;
|
AuSPtr<ISocketDriver> pSocketDriver_;
|
||||||
AuSPtr<FS::FileHandle> osHandleOwner_;
|
AuSPtr<IIOHandle> osHandleOwner_;
|
||||||
|
|
||||||
NetError error_;
|
NetError error_;
|
||||||
|
|
||||||
|
@ -243,8 +243,6 @@ namespace Aurora::IO::Net
|
|||||||
auto er = WSAGetLastError();
|
auto er = WSAGetLastError();
|
||||||
if (bReturnValue)
|
if (bReturnValue)
|
||||||
{
|
{
|
||||||
::SetEvent(this->GetAlertable());
|
|
||||||
this->DispatchCb(this->dwLastAbstractStat);
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
else if (er == ERROR_IO_PENDING)
|
else if (er == ERROR_IO_PENDING)
|
||||||
@ -276,6 +274,7 @@ namespace Aurora::IO::Net
|
|||||||
}
|
}
|
||||||
|
|
||||||
this->pMemoryHold.reset();
|
this->pMemoryHold.reset();
|
||||||
|
this->pPin.reset();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -371,7 +371,7 @@ namespace Aurora::Processes
|
|||||||
|
|
||||||
if (this->startup_.fwdIn == EStreamForward::eAsyncPipe || this->startup_.fwdOut == EStreamForward::eAsyncPipe)
|
if (this->startup_.fwdIn == EStreamForward::eAsyncPipe || this->startup_.fwdOut == EStreamForward::eAsyncPipe)
|
||||||
{
|
{
|
||||||
this->fsHandle_ = AuMakeShared<IO::FS::FileHandle>();
|
this->fsHandle_ = AuIO::IOHandleShared();
|
||||||
if (!this->fsHandle_)
|
if (!this->fsHandle_)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
@ -383,13 +383,13 @@ namespace Aurora::Processes
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
this->fsHandle_->Init(this->pipeStdOutRead_, this->pipeStdInWrite_);
|
this->fsHandle_->InitFromPairMove((AuUInt64)this->pipeStdOutRead_, (AuUInt64)this->pipeStdInWrite_);
|
||||||
this->fsStream_->Init(this->fsHandle_);
|
this->fsStream_->Init(this->fsHandle_);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this->startup_.fwdErr == EStreamForward::eAsyncPipe)
|
if (this->startup_.fwdErr == EStreamForward::eAsyncPipe)
|
||||||
{
|
{
|
||||||
this->fsErrorHandle_ = AuMakeShared<IO::FS::FileHandle>();
|
this->fsErrorHandle_ = AuIO::IOHandleShared();
|
||||||
if (!this->fsErrorHandle_)
|
if (!this->fsErrorHandle_)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
@ -401,7 +401,7 @@ namespace Aurora::Processes
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
this->fsErrorHandle_->Init(this->pipeStdErrRead_, INVALID_HANDLE_VALUE);
|
this->fsErrorHandle_->InitFromPairMove((AuUInt64)this->pipeStdErrRead_, {});
|
||||||
this->fsErrorStream_->Init(this->fsErrorHandle_);
|
this->fsErrorStream_->Init(this->fsErrorHandle_);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -59,10 +59,10 @@ namespace Aurora::Processes
|
|||||||
|
|
||||||
AuSPtr<AuLoop::ILoopSource> loopSource_;
|
AuSPtr<AuLoop::ILoopSource> loopSource_;
|
||||||
|
|
||||||
AuSPtr<IO::FS::FileHandle> fsHandle_;
|
AuSPtr<IO::IIOHandle> fsHandle_;
|
||||||
AuSPtr<IO::FS::NtAsyncFileStream> fsStream_;
|
AuSPtr<IO::FS::NtAsyncFileStream> fsStream_;
|
||||||
|
|
||||||
AuSPtr<IO::FS::FileHandle> fsErrorHandle_;
|
AuSPtr<IO::IIOHandle> fsErrorHandle_;
|
||||||
AuSPtr<IO::FS::NtAsyncFileStream> fsErrorStream_;
|
AuSPtr<IO::FS::NtAsyncFileStream> fsErrorStream_;
|
||||||
|
|
||||||
StartupParmaters startup_;
|
StartupParmaters startup_;
|
||||||
|
Loading…
Reference in New Issue
Block a user