[+] IOHandle::IsWriteEoSOnClose
[+] IOHandle::SetWriteEoSOnClose [+] IOHandle::HandleCreate::bFlushOnClose [+] IOHandle::HandleCreate::bWriteEoSOnClose [*] Unified grug based auto-truncating. Previously we were truncating on the final derefing thread; now, we truncate on the grug thread. [*] Refactor/Cleanup IOHandle
This commit is contained in:
parent
30fa15b726
commit
232a136bfe
@ -13,10 +13,13 @@
|
|||||||
namespace Aurora::IO
|
namespace Aurora::IO
|
||||||
{
|
{
|
||||||
// Note: A handle is never disposable to prevent IO fd use after close
|
// 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.
|
// You must ensure RAII and/or shared-ownership release to dispose of the IO resource.
|
||||||
// This class is only intended to be an handle view; therefore, it is not possible to close the handle.
|
// This class is only intended to be a handle view; therefore, it is not possible to close the handle.
|
||||||
//
|
//
|
||||||
// You should use the AuIOHandle or AuIO::IOHandle aliases for construction
|
// Warning: if for some reason you need to wait until any given handle is closed,
|
||||||
|
// you should ensure the handle is out of scope, then make a call to Aurora::RuntimeWaitForSecondaryTick();
|
||||||
|
//
|
||||||
|
// You should use the AuIOHandle or AuIO::IOHandle aliases for SOO construction; although, allocating functions AuIO::IOHandleShared/Unique/New are available.
|
||||||
struct IIOHandle
|
struct IIOHandle
|
||||||
{
|
{
|
||||||
struct HandleCreate
|
struct HandleCreate
|
||||||
@ -52,9 +55,20 @@ namespace Aurora::IO
|
|||||||
bool bAsyncHandle { false };
|
bool bAsyncHandle { false };
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Indicates the handle will only ever directly interface with the disk hardware as opposed to leveraging kernel assigned user shared memory
|
* Indicates the handle will only ever directly interface with the disk hardware/IO stack, as opposed to leveraging kernel assigned shared user memory.
|
||||||
|
* In this mode, only alignment/chunks of AuUInt32 AuFS::GetLogicalSectorSizeFromPath(const AuString &fileOrDirPath) is guaranteed to be accessible.
|
||||||
*/
|
*/
|
||||||
bool bDirectIOMode { false };
|
bool bDirectIOMode { false };
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Force flush on close?
|
||||||
|
*/
|
||||||
|
bool bFlushOnClose { false };
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Auto-truncate?
|
||||||
|
*/
|
||||||
|
bool bWriteEoSOnClose { false };
|
||||||
|
|
||||||
cstatic HandleCreate Create(const AuString &path)
|
cstatic HandleCreate Create(const AuString &path)
|
||||||
{
|
{
|
||||||
@ -90,7 +104,9 @@ namespace Aurora::IO
|
|||||||
}
|
}
|
||||||
|
|
||||||
inline HandleCreate(const AuString &path) :
|
inline HandleCreate(const AuString &path) :
|
||||||
path(path)
|
path(path),
|
||||||
|
eAdvisoryLevel(FS::EFileAdvisoryLockLevel::eNoSafety),
|
||||||
|
eMode(FS::EFileOpenMode::eRead)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -105,11 +121,11 @@ namespace Aurora::IO
|
|||||||
|
|
||||||
virtual bool InitFromMove(AuUInt64 uOSHandle) = 0;
|
virtual bool InitFromMove(AuUInt64 uOSHandle) = 0;
|
||||||
|
|
||||||
virtual bool InitFromPair(AuOptionalEx<AuUInt64> optOSReadHandle,
|
virtual bool InitFromPair(AuOptional<AuUInt64> optOSReadHandle,
|
||||||
AuOptionalEx<AuUInt64> optOSWriteHandle) = 0;
|
AuOptional<AuUInt64> optOSWriteHandle) = 0;
|
||||||
|
|
||||||
virtual bool InitFromPairMove(AuOptionalEx<AuUInt64> optOSReadHandle,
|
virtual bool InitFromPairMove(AuOptional<AuUInt64> optOSReadHandle,
|
||||||
AuOptionalEx<AuUInt64> optOSWriteHandle) = 0;
|
AuOptional<AuUInt64> optOSWriteHandle) = 0;
|
||||||
|
|
||||||
virtual bool InitFromStreamEnum(EStandardStream eStream) = 0;
|
virtual bool InitFromStreamEnum(EStandardStream eStream) = 0;
|
||||||
|
|
||||||
@ -117,15 +133,15 @@ namespace Aurora::IO
|
|||||||
|
|
||||||
virtual AuUInt64 GetOSHandle() const = 0;
|
virtual AuUInt64 GetOSHandle() const = 0;
|
||||||
|
|
||||||
virtual AuOptionalEx<AuUInt64> GetOSHandleSafe() const = 0;
|
virtual AuOptional<AuUInt64> GetOSHandleSafe() const = 0;
|
||||||
|
|
||||||
virtual AuUInt64 GetOSReadHandle() const = 0;
|
virtual AuUInt64 GetOSReadHandle() const = 0;
|
||||||
|
|
||||||
virtual AuOptionalEx<AuUInt64> GetOSReadHandleSafe() const = 0;
|
virtual AuOptional<AuUInt64> GetOSReadHandleSafe() const = 0;
|
||||||
|
|
||||||
virtual AuUInt64 GetOSWriteHandle() const = 0;
|
virtual AuUInt64 GetOSWriteHandle() const = 0;
|
||||||
|
|
||||||
virtual AuOptionalEx<AuUInt64> GetOSWriteHandleSafe() const = 0;
|
virtual AuOptional<AuUInt64> GetOSWriteHandleSafe() const = 0;
|
||||||
|
|
||||||
virtual bool IsValid() const = 0;
|
virtual bool IsValid() const = 0;
|
||||||
|
|
||||||
@ -133,12 +149,18 @@ namespace Aurora::IO
|
|||||||
|
|
||||||
virtual bool IsAsync() const = 0;
|
virtual bool IsAsync() const = 0;
|
||||||
|
|
||||||
virtual AuString GetPath() const = 0;
|
virtual const AuString &GetPath() const = 0;
|
||||||
|
|
||||||
virtual bool IsFlushOnClose() const = 0;
|
virtual bool IsFlushOnClose() const = 0;
|
||||||
|
|
||||||
virtual void SetFlushOnClose(bool bFlushOnClose) = 0;
|
virtual void SetFlushOnClose(bool bFlushOnClose) = 0;
|
||||||
|
|
||||||
|
// aka truncate on close
|
||||||
|
virtual bool IsWriteEoSOnClose() const = 0;
|
||||||
|
|
||||||
|
// aka truncate on close
|
||||||
|
virtual void SetWriteEoSOnClose(bool bWriteEoSOnClose) = 0;
|
||||||
|
|
||||||
virtual bool IsFile() const = 0;
|
virtual bool IsFile() const = 0;
|
||||||
|
|
||||||
virtual bool IsTTY() const = 0;
|
virtual bool IsTTY() const = 0;
|
||||||
|
@ -771,6 +771,33 @@ namespace Aurora
|
|||||||
SysUnreachable();
|
SysUnreachable();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void NTWriteEoS(HANDLE hHandle)
|
||||||
|
{
|
||||||
|
SetEndOfFile(hHandle);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SysWriteEoS(AuUInt uOSHandle)
|
||||||
|
{
|
||||||
|
NTWriteEoS((HANDLE)uOSHandle);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SysCloseHandle(AuUInt uOSHandle)
|
||||||
|
{
|
||||||
|
auto pHandle = (void *)uOSHandle;
|
||||||
|
AuWin32CloseHandle(pHandle);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SysHandleIsNonZero(AuUInt uOSHandle)
|
||||||
|
{
|
||||||
|
return uOSHandle && (void *)uOSHandle != INVALID_HANDLE_VALUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SysFlushHandle(AuUInt uOSHandle)
|
||||||
|
{
|
||||||
|
auto pHandle = (void *)uOSHandle;
|
||||||
|
FlushFileBuffers(pHandle);
|
||||||
|
}
|
||||||
|
|
||||||
AuUInt64 SysGetFileLength(AuUInt uOSHandle)
|
AuUInt64 SysGetFileLength(AuUInt uOSHandle)
|
||||||
{
|
{
|
||||||
LARGE_INTEGER length;
|
LARGE_INTEGER length;
|
||||||
|
@ -1228,6 +1228,8 @@ namespace Aurora
|
|||||||
LPCSTR lpProcName
|
LPCSTR lpProcName
|
||||||
);
|
);
|
||||||
|
|
||||||
|
void NTWriteEoS(HANDLE hHandle);
|
||||||
|
|
||||||
static auline bool SysWaitOnAddressNoTimed(const void *pTargetAddress,
|
static auline bool SysWaitOnAddressNoTimed(const void *pTargetAddress,
|
||||||
const void *pCompareAddress,
|
const void *pCompareAddress,
|
||||||
AuUInt8 uWordSize)
|
AuUInt8 uWordSize)
|
||||||
|
@ -161,6 +161,40 @@ namespace Aurora
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void PosixWriteEoS(int fd)
|
||||||
|
{
|
||||||
|
::ftruncate(fd, PosixGetOffset(fd));
|
||||||
|
}
|
||||||
|
|
||||||
|
void SysWriteEoS(AuUInt uOSHandle)
|
||||||
|
{
|
||||||
|
PosixWriteEoS(uOSHandle);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SysCloseHandle(AuUInt uOSHandle)
|
||||||
|
{
|
||||||
|
::close(uOSHandle);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SysHandleIsNonZero(AuUInt uOSHandle)
|
||||||
|
{
|
||||||
|
#if defined(AURORA_IS_64BIT)
|
||||||
|
return uOSHandle && (uOSHandle != 0xFFFFFFFFull) && (uOSHandle != 0xFFFFFFFFFFFFFFFFull);
|
||||||
|
#else
|
||||||
|
return uOSHandle && (uOSHandle != 0xFFFFFFFF);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void SysFlushHandle(AuUInt uOSHandle)
|
||||||
|
{
|
||||||
|
::fsync(uOSHandle);
|
||||||
|
}
|
||||||
|
|
||||||
|
int PosixUnlink(const char *pathname)
|
||||||
|
{
|
||||||
|
return ::unlink(pathname);
|
||||||
|
}
|
||||||
|
|
||||||
AuUInt64 SysGetFileLength(AuUInt uOSHandle)
|
AuUInt64 SysGetFileLength(AuUInt uOSHandle)
|
||||||
{
|
{
|
||||||
return PosixGetLength(uOSHandle);
|
return PosixGetLength(uOSHandle);
|
||||||
|
@ -23,4 +23,7 @@ namespace Aurora
|
|||||||
AuUInt64 PosixGetLength(int fd);
|
AuUInt64 PosixGetLength(int fd);
|
||||||
bool PosixRead (int fd, void *buf, AuUInt32 count, AuUInt32 *pRead);
|
bool PosixRead (int fd, void *buf, AuUInt32 count, AuUInt32 *pRead);
|
||||||
bool PosixWrite (int fd, const void *buf, AuUInt32 count, AuUInt32 *pWritten);
|
bool PosixWrite (int fd, const void *buf, AuUInt32 count, AuUInt32 *pWritten);
|
||||||
|
void PosixWriteEoS (int fd);
|
||||||
|
|
||||||
|
int PosixUnlink (const char *pathname);
|
||||||
}
|
}
|
@ -48,6 +48,14 @@ namespace Aurora
|
|||||||
|
|
||||||
AuUInt64 SysGetFileLength(AuUInt uOSHandle);
|
AuUInt64 SysGetFileLength(AuUInt uOSHandle);
|
||||||
|
|
||||||
|
void SysWriteEoS(AuUInt uOSHandle);
|
||||||
|
|
||||||
|
void SysFlushHandle(AuUInt uOSHandle);
|
||||||
|
|
||||||
|
void SysCloseHandle(AuUInt uOSHandle);
|
||||||
|
|
||||||
|
bool SysHandleIsNonZero(AuUInt uOSHandle);
|
||||||
|
|
||||||
void *SysAllocateLarge(AuUInt uLength);
|
void *SysAllocateLarge(AuUInt uLength);
|
||||||
|
|
||||||
void SysAllocateFree(void *pBuffer, AuUInt uLength);
|
void SysAllocateFree(void *pBuffer, AuUInt uLength);
|
||||||
|
@ -34,7 +34,7 @@ namespace Aurora::Grug
|
|||||||
static AuSemaphore gArrows;
|
static AuSemaphore gArrows;
|
||||||
static AuBinarySemaphore gArrowsRetarded(false, true, true);
|
static AuBinarySemaphore gArrowsRetarded(false, true, true);
|
||||||
static AuMutex gOtherMutex;
|
static AuMutex gOtherMutex;
|
||||||
static AuList<AuPair<AuUInt, bool>> gHandlesToClose;
|
static AuList<AuTuple<AuUInt, bool, bool>> gHandlesToClose;
|
||||||
static AuList<AuThreadPrimitives::IEvent *> gEventsToTrigger;
|
static AuList<AuThreadPrimitives::IEvent *> gEventsToTrigger;
|
||||||
|
|
||||||
static void SlowStartupTasks()
|
static void SlowStartupTasks()
|
||||||
@ -189,25 +189,29 @@ namespace Aurora::Grug
|
|||||||
toTrigger = AuMove(gEventsToTrigger);
|
toTrigger = AuMove(gEventsToTrigger);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (const auto [uHandle, bFlush] : toClose)
|
for (const auto [uHandle, bFlush, bWriteEoS] : toClose)
|
||||||
{
|
{
|
||||||
#if defined(AURORA_IS_MODERNNT_DERIVED)
|
if (!SysHandleIsNonZero(uHandle))
|
||||||
auto pHandle = (void *)uHandle;
|
|
||||||
if (bFlush && pHandle)
|
|
||||||
{
|
{
|
||||||
if (AuIO::IsHandleFile(uHandle))
|
continue;
|
||||||
{
|
|
||||||
FlushFileBuffers(pHandle);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
AuWin32CloseHandle(pHandle);
|
|
||||||
#elif defined(AURORA_IS_POSIX_DERIVED)
|
if (bWriteEoS)
|
||||||
|
{
|
||||||
|
SysWriteEoS(uHandle);
|
||||||
|
}
|
||||||
|
|
||||||
if (bFlush)
|
if (bFlush)
|
||||||
{
|
{
|
||||||
::fsync(uHandle);
|
#if defined(AURORA_IS_MODERNNT_DERIVED)
|
||||||
|
if (AuIO::IsHandleFile(uHandle))
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
SysFlushHandle(uHandle);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
::close(uHandle);
|
|
||||||
#endif
|
SysCloseHandle(uHandle);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (const auto pEvent : toTrigger)
|
for (const auto pEvent : toTrigger)
|
||||||
@ -224,12 +228,12 @@ namespace Aurora::Grug
|
|||||||
GrugDoIoWork();
|
GrugDoIoWork();
|
||||||
}
|
}
|
||||||
|
|
||||||
void CloseHandle(AuUInt64 handle, bool bFlush)
|
void CloseHandle(AuUInt64 handle, bool bFlush, bool bWriteEoS)
|
||||||
{
|
{
|
||||||
{
|
{
|
||||||
AU_DEBUG_MEMCRUNCH;
|
AU_DEBUG_MEMCRUNCH;
|
||||||
AU_LOCK_GUARD(gOtherMutex);
|
AU_LOCK_GUARD(gOtherMutex);
|
||||||
gHandlesToClose.push_back(AuMakePair(AuUInt(handle), bFlush));
|
gHandlesToClose.push_back(AuMakeTuple(AuUInt(handle), bFlush, bWriteEoS));
|
||||||
}
|
}
|
||||||
|
|
||||||
NotifyGrugOfTelemetry();
|
NotifyGrugOfTelemetry();
|
||||||
|
@ -24,6 +24,6 @@ namespace Aurora::Grug
|
|||||||
void InitGrug();
|
void InitGrug();
|
||||||
void DeinitGrug();
|
void DeinitGrug();
|
||||||
|
|
||||||
void CloseHandle(AuUInt64 handle, bool bFlush = false);
|
void CloseHandle(AuUInt64 handle, bool bFlush = false, bool bWriteEoS = false);
|
||||||
void WaitForGrugTick();
|
void WaitForGrugTick();
|
||||||
}
|
}
|
@ -40,13 +40,13 @@ namespace Aurora::IO
|
|||||||
return AuUInt64(hHandle);
|
return AuUInt64(hHandle);
|
||||||
}
|
}
|
||||||
|
|
||||||
void AFileHandle::CloseHandle(AuUInt64 uOSHandle, bool bFlushOnClose)
|
void AFileHandle::CloseHandle(AuUInt64 uOSHandle, bool bFlushOnClose, bool bWriteEoS)
|
||||||
{
|
{
|
||||||
#if 0
|
#if 0
|
||||||
HANDLE hHandle = (HANDLE)uOSHandle;
|
HANDLE hHandle = (HANDLE)uOSHandle;
|
||||||
AuWin32CloseHandle(hHandle);
|
AuWin32CloseHandle(hHandle);
|
||||||
#else
|
#else
|
||||||
Grug::CloseHandle(uOSHandle, bFlushOnClose);
|
Grug::CloseHandle(uOSHandle, bFlushOnClose, bWriteEoS);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -313,6 +313,8 @@ namespace Aurora::IO
|
|||||||
}
|
}
|
||||||
|
|
||||||
this->bIsAsync = create.bAsyncHandle;
|
this->bIsAsync = create.bAsyncHandle;
|
||||||
|
this->bShouldWriteEoS = create.bWriteEoSOnClose;
|
||||||
|
this->bFlushOnClose = create.bFlushOnClose;
|
||||||
|
|
||||||
this->path = create.path;
|
this->path = create.path;
|
||||||
|
|
||||||
|
@ -85,7 +85,7 @@ namespace Aurora::IO
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
void AFileHandle::CloseHandle(AuUInt64 uOSHandle, bool bFlushOnClose)
|
void AFileHandle::CloseHandle(AuUInt64 uOSHandle, bool bFlushOnClose, bool bWriteEoS)
|
||||||
{
|
{
|
||||||
int fd = (int)uOSHandle;
|
int fd = (int)uOSHandle;
|
||||||
if (fd < 0)
|
if (fd < 0)
|
||||||
@ -100,7 +100,7 @@ namespace Aurora::IO
|
|||||||
}
|
}
|
||||||
::close(fd);
|
::close(fd);
|
||||||
#else
|
#else
|
||||||
Grug::CloseHandle(uOSHandle, bFlushOnClose);
|
Grug::CloseHandle(uOSHandle, bFlushOnClose, bWriteEoS);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -284,6 +284,8 @@ namespace Aurora::IO
|
|||||||
};
|
};
|
||||||
|
|
||||||
this->bIsAsync = create.bAsyncHandle;
|
this->bIsAsync = create.bAsyncHandle;
|
||||||
|
this->bShouldWriteEoS = create.bWriteEoSOnClose;
|
||||||
|
this->bFlushOnClose = create.bFlushOnClose;
|
||||||
|
|
||||||
this->path = create.path;
|
this->path = create.path;
|
||||||
|
|
||||||
|
@ -31,23 +31,28 @@ namespace Aurora::IO
|
|||||||
this->SharingStop();
|
this->SharingStop();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (this->pThat)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (this->uOSWriteHandle.HasValue() && this->uOSReadHandle.HasValue() &&
|
if (this->uOSWriteHandle.HasValue() && this->uOSReadHandle.HasValue() &&
|
||||||
this->uOSReadHandle.Value() == this->uOSWriteHandle.Value())
|
this->uOSReadHandle.Value() == this->uOSWriteHandle.Value())
|
||||||
{
|
{
|
||||||
this->CloseHandle(this->uOSReadHandle.Value());
|
this->CloseHandle(this->uOSReadHandle.Value(), this->bFlushOnClose, this->bShouldWriteEoS);
|
||||||
AuResetMember(this->uOSReadHandle);
|
AuResetMember(this->uOSReadHandle);
|
||||||
AuResetMember(this->uOSWriteHandle);
|
AuResetMember(this->uOSWriteHandle);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this->uOSReadHandle)
|
if (this->uOSReadHandle)
|
||||||
{
|
{
|
||||||
this->CloseHandle(this->uOSReadHandle.Value());
|
this->CloseHandle(this->uOSReadHandle.Value(), false, false);
|
||||||
AuResetMember(this->uOSReadHandle);
|
AuResetMember(this->uOSReadHandle);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this->uOSWriteHandle)
|
if (this->uOSWriteHandle)
|
||||||
{
|
{
|
||||||
this->CloseHandle(this->uOSWriteHandle.Value());
|
AFileHandle::CloseHandle(this->uOSWriteHandle.Value(), this->bFlushOnClose, this->bShouldWriteEoS);
|
||||||
AuResetMember(this->uOSWriteHandle);
|
AuResetMember(this->uOSWriteHandle);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -105,8 +110,8 @@ namespace Aurora::IO
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool AFileHandle::InitFromPair(AuOptionalEx<AuUInt64> optOSReadHandle,
|
bool AFileHandle::InitFromPair(AuOptional<AuUInt64> optOSReadHandle,
|
||||||
AuOptionalEx<AuUInt64> optOSWriteHandle)
|
AuOptional<AuUInt64> optOSWriteHandle)
|
||||||
{
|
{
|
||||||
if (this->IsValid())
|
if (this->IsValid())
|
||||||
{
|
{
|
||||||
@ -144,8 +149,8 @@ namespace Aurora::IO
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool AFileHandle::InitFromPairMove(AuOptionalEx<AuUInt64> uOSReadHandle,
|
bool AFileHandle::InitFromPairMove(AuOptional<AuUInt64> uOSReadHandle,
|
||||||
AuOptionalEx<AuUInt64> uOSWriteHandle)
|
AuOptional<AuUInt64> uOSWriteHandle)
|
||||||
{
|
{
|
||||||
if (this->IsValid())
|
if (this->IsValid())
|
||||||
{
|
{
|
||||||
@ -232,6 +237,16 @@ namespace Aurora::IO
|
|||||||
this->bFlushOnClose = bFlushOnClose;
|
this->bFlushOnClose = bFlushOnClose;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool AFileHandle::IsWriteEoSOnClose() const
|
||||||
|
{
|
||||||
|
return this->bShouldWriteEoS;
|
||||||
|
}
|
||||||
|
|
||||||
|
void AFileHandle::SetWriteEoSOnClose(bool bShouldWriteEoS)
|
||||||
|
{
|
||||||
|
this->bShouldWriteEoS = bShouldWriteEoS;
|
||||||
|
}
|
||||||
|
|
||||||
bool AFileHandle::IsPipe() const
|
bool AFileHandle::IsPipe() const
|
||||||
{
|
{
|
||||||
bool bIsPipe {};
|
bool bIsPipe {};
|
||||||
@ -255,7 +270,7 @@ namespace Aurora::IO
|
|||||||
return bIsPipe;
|
return bIsPipe;
|
||||||
}
|
}
|
||||||
|
|
||||||
AuOptionalEx<AuUInt64> AFileHandle::GetOSHandleSafe() const
|
AuOptional<AuUInt64> AFileHandle::GetOSHandleSafe() const
|
||||||
{
|
{
|
||||||
if (auto write = this->uOSWriteHandle)
|
if (auto write = this->uOSWriteHandle)
|
||||||
{
|
{
|
||||||
@ -283,7 +298,7 @@ namespace Aurora::IO
|
|||||||
return this->uOSReadHandle.Value();
|
return this->uOSReadHandle.Value();
|
||||||
}
|
}
|
||||||
|
|
||||||
AuOptionalEx<AuUInt64> AFileHandle::GetOSReadHandleSafe() const
|
AuOptional<AuUInt64> AFileHandle::GetOSReadHandleSafe() const
|
||||||
{
|
{
|
||||||
return this->uOSReadHandle;
|
return this->uOSReadHandle;
|
||||||
}
|
}
|
||||||
@ -293,7 +308,7 @@ namespace Aurora::IO
|
|||||||
return this->uOSWriteHandle.Value();
|
return this->uOSWriteHandle.Value();
|
||||||
}
|
}
|
||||||
|
|
||||||
AuOptionalEx<AuUInt64> AFileHandle::GetOSWriteHandleSafe() const
|
AuOptional<AuUInt64> AFileHandle::GetOSWriteHandleSafe() const
|
||||||
{
|
{
|
||||||
return this->uOSWriteHandle;
|
return this->uOSWriteHandle;
|
||||||
}
|
}
|
||||||
@ -314,7 +329,7 @@ namespace Aurora::IO
|
|||||||
return this->bIsAsync;
|
return this->bIsAsync;
|
||||||
}
|
}
|
||||||
|
|
||||||
AuString AFileHandle::GetPath() const
|
const AuString &AFileHandle::GetPath() const
|
||||||
{
|
{
|
||||||
return this->path;
|
return this->path;
|
||||||
}
|
}
|
||||||
|
@ -26,11 +26,11 @@ namespace Aurora::IO
|
|||||||
|
|
||||||
bool InitFromMove(AuUInt64 uOSHandle) override;
|
bool InitFromMove(AuUInt64 uOSHandle) override;
|
||||||
|
|
||||||
bool InitFromPair(AuOptionalEx<AuUInt64> uOSReadHandle,
|
bool InitFromPair(AuOptional<AuUInt64> uOSReadHandle,
|
||||||
AuOptionalEx<AuUInt64> uOSWriteHandle) override;
|
AuOptional<AuUInt64> uOSWriteHandle) override;
|
||||||
|
|
||||||
bool InitFromPairMove(AuOptionalEx<AuUInt64> uOSReadHandle,
|
bool InitFromPairMove(AuOptional<AuUInt64> uOSReadHandle,
|
||||||
AuOptionalEx<AuUInt64> uOSWriteHandle) override;
|
AuOptional<AuUInt64> uOSWriteHandle) override;
|
||||||
|
|
||||||
bool InitFromStreamEnum(EStandardStream eStream) override;
|
bool InitFromStreamEnum(EStandardStream eStream) override;
|
||||||
|
|
||||||
@ -42,15 +42,15 @@ namespace Aurora::IO
|
|||||||
|
|
||||||
AuUInt64 GetOSHandle() const override;
|
AuUInt64 GetOSHandle() const override;
|
||||||
|
|
||||||
AuOptionalEx<AuUInt64> GetOSHandleSafe() const override;
|
AuOptional<AuUInt64> GetOSHandleSafe() const override;
|
||||||
|
|
||||||
AuUInt64 GetOSReadHandle() const override;
|
AuUInt64 GetOSReadHandle() const override;
|
||||||
|
|
||||||
AuOptionalEx<AuUInt64> GetOSReadHandleSafe() const override;
|
AuOptional<AuUInt64> GetOSReadHandleSafe() const override;
|
||||||
|
|
||||||
AuUInt64 GetOSWriteHandle() const override;
|
AuUInt64 GetOSWriteHandle() const override;
|
||||||
|
|
||||||
AuOptionalEx<AuUInt64> GetOSWriteHandleSafe() const override;
|
AuOptional<AuUInt64> GetOSWriteHandleSafe() const override;
|
||||||
|
|
||||||
bool IsValid() const override;
|
bool IsValid() const override;
|
||||||
|
|
||||||
@ -58,7 +58,7 @@ namespace Aurora::IO
|
|||||||
|
|
||||||
bool IsAsync() const override;
|
bool IsAsync() const override;
|
||||||
|
|
||||||
AuString GetPath() const override;
|
const AuString &GetPath() const override;
|
||||||
|
|
||||||
bool IsFile() const override;
|
bool IsFile() const override;
|
||||||
bool IsTTY() const override;
|
bool IsTTY() const override;
|
||||||
@ -67,6 +67,9 @@ namespace Aurora::IO
|
|||||||
bool IsFlushOnClose() const override;
|
bool IsFlushOnClose() const override;
|
||||||
void SetFlushOnClose(bool bFlushOnClose) override;
|
void SetFlushOnClose(bool bFlushOnClose) override;
|
||||||
|
|
||||||
|
bool IsWriteEoSOnClose() const override;
|
||||||
|
void SetWriteEoSOnClose(bool bShouldWriteEoS) override;
|
||||||
|
|
||||||
void InitStdIn(bool bSharing = false);
|
void InitStdIn(bool bSharing = false);
|
||||||
void InitStdOut(bool bError = false, bool bSharing = false);
|
void InitStdOut(bool bError = false, bool bSharing = false);
|
||||||
|
|
||||||
@ -85,18 +88,17 @@ namespace Aurora::IO
|
|||||||
|
|
||||||
bool ShouldClone();
|
bool ShouldClone();
|
||||||
|
|
||||||
AuOptionalEx<AuUInt64> uOSWriteHandle;
|
AuOptional<AuUInt64> uOSWriteHandle;
|
||||||
AuOptionalEx<AuUInt64> uOSReadHandle;
|
AuOptional<AuUInt64> uOSReadHandle;
|
||||||
AuSPtr<IIOHandle> pThat;
|
AuSPtr<IIOHandle> pThat;
|
||||||
bool bIsAsync {}, bFlushOnClose {};
|
|
||||||
AuString path;
|
AuString path;
|
||||||
IPC::IPCPipeImpl *pIPCPipe {};
|
IPC::IPCPipeImpl *pIPCPipe {};
|
||||||
bool bDirectIO {};
|
|
||||||
mutable AuOptional<bool> optIsFile;
|
mutable AuOptional<bool> optIsFile;
|
||||||
mutable AuOptional<bool> optIsPipe;
|
mutable AuOptional<bool> optIsPipe;
|
||||||
mutable AuOptional<bool> optIsTTY;
|
mutable AuOptional<bool> optIsTTY;
|
||||||
mutable AuSPtr<AuString> pIPCString;
|
mutable AuSPtr<AuString> pIPCString;
|
||||||
AuUInt uThreadId {};
|
AuUInt uThreadId {};
|
||||||
|
bool bIsAsync {}, bFlushOnClose {}, bShouldWriteEoS {}, bDirectIO {};
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
// Implement me:
|
// Implement me:
|
||||||
@ -105,11 +107,11 @@ namespace Aurora::IO
|
|||||||
|
|
||||||
static AuUInt64 DupHandle(AuUInt64 uOSHandle, bool bWriteAccess);
|
static AuUInt64 DupHandle(AuUInt64 uOSHandle, bool bWriteAccess);
|
||||||
static AuUInt64 DupHandle(AuUInt64 uOSHandle, bool bWriteAccess, bool bShareAccess);
|
static AuUInt64 DupHandle(AuUInt64 uOSHandle, bool bWriteAccess, bool bShareAccess);
|
||||||
static void CloseHandle(AuUInt64 uOSHandle, bool bFlushOnClose);
|
static void CloseHandle(AuUInt64 uOSHandle, bool bFlushOnClose, bool bWriteEoS);
|
||||||
|
|
||||||
inline void CloseHandle(AuUInt64 uOSHandle)
|
inline void CloseHandle(AuUInt64 uOSHandle)
|
||||||
{
|
{
|
||||||
CloseHandle(uOSHandle, this->bFlushOnClose);
|
CloseHandle(uOSHandle, this->bFlushOnClose, false);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
@ -406,7 +406,7 @@ namespace Aurora::IO::FS
|
|||||||
}
|
}
|
||||||
else if (errno == ENOTDIR)
|
else if (errno == ENOTDIR)
|
||||||
{
|
{
|
||||||
if (::unlink(pathExpanded.c_str()) == 0)
|
if (PosixUnlink(pathExpanded.c_str()) == 0)
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -415,7 +415,7 @@ namespace Aurora::IO::FS
|
|||||||
|
|
||||||
if (S_ISREG(s.st_mode))
|
if (S_ISREG(s.st_mode))
|
||||||
{
|
{
|
||||||
if (::unlink(pathExpanded.c_str()) == 0)
|
if (PosixUnlink(pathExpanded.c_str()) == 0)
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -386,7 +386,7 @@ namespace Aurora::IO::FS
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
SetEndOfFile(hHandle);
|
NTWriteEoS(hHandle);
|
||||||
}
|
}
|
||||||
|
|
||||||
void WinFileStream::Close()
|
void WinFileStream::Close()
|
||||||
@ -397,10 +397,6 @@ namespace Aurora::IO::FS
|
|||||||
bool bDeleteFailed {};
|
bool bDeleteFailed {};
|
||||||
AuString path;
|
AuString path;
|
||||||
|
|
||||||
if (this->bShouldWriteEoS)
|
|
||||||
{
|
|
||||||
this->WriteEoS();
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((hHandle != INVALID_HANDLE_VALUE) &&
|
if ((hHandle != INVALID_HANDLE_VALUE) &&
|
||||||
(this->bShouldDelete))
|
(this->bShouldDelete))
|
||||||
@ -430,6 +426,7 @@ namespace Aurora::IO::FS
|
|||||||
// a bit of a hack for problematic NT-like platforms and Windows XP
|
// a bit of a hack for problematic NT-like platforms and Windows XP
|
||||||
if (bDeleteFailed)
|
if (bDeleteFailed)
|
||||||
{
|
{
|
||||||
|
Aurora::RuntimeWaitForSecondaryTick();
|
||||||
AuFS::Remove(path);
|
AuFS::Remove(path);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -450,7 +447,7 @@ namespace Aurora::IO::FS
|
|||||||
{
|
{
|
||||||
AU_LOCK_GUARD(this->mutex_);
|
AU_LOCK_GUARD(this->mutex_);
|
||||||
|
|
||||||
if (auto pHandle = this->pHandle_)
|
if (auto &pHandle = this->pHandle_)
|
||||||
{
|
{
|
||||||
return pHandle->IsFlushOnClose();
|
return pHandle->IsFlushOnClose();
|
||||||
}
|
}
|
||||||
@ -464,7 +461,7 @@ namespace Aurora::IO::FS
|
|||||||
{
|
{
|
||||||
AU_LOCK_GUARD(this->mutex_);
|
AU_LOCK_GUARD(this->mutex_);
|
||||||
|
|
||||||
if (auto pHandle = this->pHandle_)
|
if (auto &pHandle = this->pHandle_)
|
||||||
{
|
{
|
||||||
pHandle->SetFlushOnClose(bFlushOnClose);
|
pHandle->SetFlushOnClose(bFlushOnClose);
|
||||||
}
|
}
|
||||||
@ -472,12 +469,26 @@ namespace Aurora::IO::FS
|
|||||||
|
|
||||||
bool WinFileStream::IsWriteEoSOnClose() const
|
bool WinFileStream::IsWriteEoSOnClose() const
|
||||||
{
|
{
|
||||||
return this->bShouldWriteEoS;
|
AU_LOCK_GUARD(this->mutex_);
|
||||||
|
|
||||||
|
if (auto &pHandle = this->pHandle_)
|
||||||
|
{
|
||||||
|
return pHandle->IsWriteEoSOnClose();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void WinFileStream::SetWriteEoSOnClose(bool bShouldWriteEoS)
|
void WinFileStream::SetWriteEoSOnClose(bool bShouldWriteEoS)
|
||||||
{
|
{
|
||||||
this->bShouldWriteEoS = bShouldWriteEoS;
|
AU_LOCK_GUARD(this->mutex_);
|
||||||
|
|
||||||
|
if (auto &pHandle = this->pHandle_)
|
||||||
|
{
|
||||||
|
pHandle->SetWriteEoSOnClose(bShouldWriteEoS);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
AuSPtr<IIOHandle> WinFileStream::GetHandle()
|
AuSPtr<IIOHandle> WinFileStream::GetHandle()
|
||||||
|
@ -41,7 +41,7 @@ namespace Aurora::IO::FS
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
AuSPtr<IIOHandle> pHandle_;
|
AuSPtr<IIOHandle> pHandle_;
|
||||||
bool bShouldDelete {}, bShouldWriteEoS {};
|
bool bShouldDelete {};
|
||||||
HANDLE hEventHandle_ { INVALID_HANDLE_VALUE };
|
HANDLE hEventHandle_ { INVALID_HANDLE_VALUE };
|
||||||
AuFS::FileReader reader_;
|
AuFS::FileReader reader_;
|
||||||
AuFS::FileWriter writer_;
|
AuFS::FileWriter writer_;
|
||||||
|
@ -5,9 +5,6 @@
|
|||||||
Date: 2021-6-12
|
Date: 2021-6-12
|
||||||
Author: Reece
|
Author: Reece
|
||||||
***/
|
***/
|
||||||
#define _FILE_OFFSET_BITS 64
|
|
||||||
#define _LARGEFILE64_SOURCE
|
|
||||||
|
|
||||||
#include <Source/RuntimeInternal.hpp>
|
#include <Source/RuntimeInternal.hpp>
|
||||||
#include "FS.hpp"
|
#include "FS.hpp"
|
||||||
#include "FileStream.Generic.hpp"
|
#include "FileStream.Generic.hpp"
|
||||||
@ -263,16 +260,12 @@ namespace Aurora::IO::FS
|
|||||||
auto pHandle = this->pHandle_;
|
auto pHandle = this->pHandle_;
|
||||||
AuResetMember(this->pHandle_);
|
AuResetMember(this->pHandle_);
|
||||||
|
|
||||||
if (this->bShouldWriteEoS)
|
|
||||||
{
|
|
||||||
this->WriteEoS();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (AuExchange(this->bMadeTemporary, false))
|
if (AuExchange(this->bMadeTemporary, false))
|
||||||
{
|
{
|
||||||
|
Aurora::RuntimeWaitForSecondaryTick();
|
||||||
if (pHandle)
|
if (pHandle)
|
||||||
{
|
{
|
||||||
::unlink(pHandle->GetPath().c_str());
|
PosixUnlink(pHandle->GetPath().c_str());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -281,7 +274,7 @@ namespace Aurora::IO::FS
|
|||||||
{
|
{
|
||||||
AU_LOCK_GUARD(this->mutex_);
|
AU_LOCK_GUARD(this->mutex_);
|
||||||
|
|
||||||
if (auto pHandle = this->pHandle_)
|
if (auto &pHandle = this->pHandle_)
|
||||||
{
|
{
|
||||||
return pHandle->IsFlushOnClose();
|
return pHandle->IsFlushOnClose();
|
||||||
}
|
}
|
||||||
@ -295,7 +288,7 @@ namespace Aurora::IO::FS
|
|||||||
{
|
{
|
||||||
AU_LOCK_GUARD(this->mutex_);
|
AU_LOCK_GUARD(this->mutex_);
|
||||||
|
|
||||||
if (auto pHandle = this->pHandle_)
|
if (auto &pHandle = this->pHandle_)
|
||||||
{
|
{
|
||||||
pHandle->SetFlushOnClose(bFlushOnClose);
|
pHandle->SetFlushOnClose(bFlushOnClose);
|
||||||
}
|
}
|
||||||
@ -303,12 +296,26 @@ namespace Aurora::IO::FS
|
|||||||
|
|
||||||
bool PosixFileStream::IsWriteEoSOnClose() const
|
bool PosixFileStream::IsWriteEoSOnClose() const
|
||||||
{
|
{
|
||||||
return this->bShouldWriteEoS;
|
AU_LOCK_GUARD(this->mutex_);
|
||||||
|
|
||||||
|
if (auto &pHandle = this->pHandle_)
|
||||||
|
{
|
||||||
|
return pHandle->IsWriteEoSOnClose();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void PosixFileStream::SetWriteEoSOnClose(bool bShouldWriteEoS)
|
void PosixFileStream::SetWriteEoSOnClose(bool bShouldWriteEoS)
|
||||||
{
|
{
|
||||||
this->bShouldWriteEoS = bShouldWriteEoS;
|
AU_LOCK_GUARD(this->mutex_);
|
||||||
|
|
||||||
|
if (auto &pHandle = this->pHandle_)
|
||||||
|
{
|
||||||
|
pHandle->SetWriteEoSOnClose(bShouldWriteEoS);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void PosixFileStream::Flush()
|
void PosixFileStream::Flush()
|
||||||
@ -328,7 +335,7 @@ namespace Aurora::IO::FS
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
::fsync(fd);
|
SysFlushHandle(fd);
|
||||||
}
|
}
|
||||||
|
|
||||||
void PosixFileStream::WriteEoS()
|
void PosixFileStream::WriteEoS()
|
||||||
@ -348,7 +355,7 @@ namespace Aurora::IO::FS
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
::ftruncate(fd, PosixGetOffset(fd));
|
PosixWriteEoS(fd);
|
||||||
}
|
}
|
||||||
|
|
||||||
void PosixFileStream::MakeTemporary()
|
void PosixFileStream::MakeTemporary()
|
||||||
|
@ -43,11 +43,11 @@ namespace Aurora::IO::FS
|
|||||||
AuSPtr<IIOHandle> pHandle_;
|
AuSPtr<IIOHandle> pHandle_;
|
||||||
AuString path_;
|
AuString path_;
|
||||||
AuMutex mutex_;
|
AuMutex mutex_;
|
||||||
bool bMadeTemporary {}, bShouldWriteEoS {};
|
|
||||||
AuFS::FileReader reader_;
|
AuFS::FileReader reader_;
|
||||||
AuFS::FileWriter writer_;
|
AuFS::FileWriter writer_;
|
||||||
AuFS::FileSeekableReader sreader_;
|
AuFS::FileSeekableReader sreader_;
|
||||||
AuFS::FileSeekableWriter swriter_;
|
AuFS::FileSeekableWriter swriter_;
|
||||||
|
bool bMadeTemporary {};
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
Loading…
Reference in New Issue
Block a user