diff --git a/Include/Aurora/IO/FS/IFileStream.hpp b/Include/Aurora/IO/FS/IFileStream.hpp index 22d042ab..38882aca 100644 --- a/Include/Aurora/IO/FS/IFileStream.hpp +++ b/Include/Aurora/IO/FS/IFileStream.hpp @@ -12,5 +12,6 @@ namespace Aurora::IO::FS virtual bool Write(const Memory::MemoryViewStreamRead ¶meters) = 0; virtual void Close() = 0; virtual void Flush() = 0; + virtual void WriteEoS() = 0; }; } \ No newline at end of file diff --git a/Include/Aurora/Processes/IProcess.hpp b/Include/Aurora/Processes/IProcess.hpp index 71f7b51e..cacdf512 100644 --- a/Include/Aurora/Processes/IProcess.hpp +++ b/Include/Aurora/Processes/IProcess.hpp @@ -34,7 +34,7 @@ namespace Aurora::Processes virtual bool TryKill() = 0; virtual bool Read(bool error, void *buffer, AuUInt32 &len) = 0; - virtual bool Read(void *buffer, AuUInt32 &len, bool errorStream = false, bool nonblock = true); + virtual bool Read(void *buffer, AuUInt32 &len, bool errorStream = false, bool nonblock = true) = 0; virtual bool Write(const void *buffer, AuUInt32 len) = 0; }; } \ No newline at end of file diff --git a/Include/Aurora/Threading/LockGuardTry.hpp b/Include/Aurora/Threading/LockGuardTry.hpp index 00a8a6ae..01046fea 100644 --- a/Include/Aurora/Threading/LockGuardTry.hpp +++ b/Include/Aurora/Threading/LockGuardTry.hpp @@ -85,11 +85,26 @@ namespace Aurora::Threading std::conditional_t, T, T*> annoying_; }; - #define AU_TRY_LOCK_GUARD(variable) Aurora::Threading::TryLockGuard AU_CONCAT(__stack_lock, __COUNTER__) (variable); - #define AU_TRY_LOCK_GUARD_RET_NAMED(variable, value, name) Aurora::Threading::TryLockGuard name (variable); if (!(name.Locked())) return value; - #define AU_TRY_LOCK_GUARD_RET(variable, value, counter) AU_TRY_LOCK_GUARD_RET_NAMED(variable, value, AU_CONCAT(__stack_lock, counter)) - #define AU_TRY_LOCK_GUARD_RET_VAL(variable, value) AU_TRY_LOCK_GUARD_RET_NAMED(variable, value, AU_WHAT(__COUNTER__)) + + // Named try-lock guard. Use when you wish to poll ::Locked(), otherwise use the auto-return macros + // There is no point in using anonymous lock handles w/o checking the lock state or auto-returning + // Where variable = an iwaitable-like interface reference, pointer, or shared pointer; value = reference to a boolean + // name = name of handle variable + #define AU_TRY_LOCK_GUARD_NAMED(variable, name) Aurora::Threading::TryLockGuard name(variable); + + /// @hideinitializer + #define AU_TRY_LOCK_GUARD_RET_NAMED(variable, value, name) AU_TRY_LOCK_GUARD_NAMED(variable, name) if (!(name.Locked())) return value; + + /// @hideinitializer + #define AU_TRY_LOCK_GUARD_RET_COUNTERVAL(variable, value, counter) AU_TRY_LOCK_GUARD_RET_NAMED(variable, value, AU_CONCAT(__stack_lock, counter)) + + // where variable = an iwaitable-like interface reference, pointer, or shared pointer; value = reference to a boolean + // value = failure return object + #define AU_TRY_LOCK_GUARD_RET_VAL(variable, value) AU_TRY_LOCK_GUARD_RET_COUNTERVAL(variable, value, AU_WHAT(__COUNTER__)) + + // where variable = an iwaitable-like interface reference, pointer, or shared pointer #define AU_TRY_LOCK_GUARD_RET_DEF(variable) AU_TRY_LOCK_GUARD_RET_VAL(variable, {}) + + // where variable = an iwaitable-like interface reference, pointer #define AU_TRY_LOCK_GUARD_RET(variable) AU_TRY_LOCK_GUARD_RET_VAL(variable, ) - #define AU_TRY_LOCK_GUARD_NAMED(variable, name) AU_TRY_LOCK_GUARD_RET_NAMED(variable, , name) } \ No newline at end of file diff --git a/Source/IO/FS/Async.NT.cpp b/Source/IO/FS/Async.NT.cpp index dbb90d83..cf12306a 100644 --- a/Source/IO/FS/Async.NT.cpp +++ b/Source/IO/FS/Async.NT.cpp @@ -228,7 +228,7 @@ namespace Aurora::IO::FS bool NtAsyncFileTransaction::Complete() { - auto ret = WaitForSingleObject(this->event_, 0); + auto ret = WaitForSingleObjectEx(this->event_, 0, true); if (ret == WAIT_OBJECT_0) { DispatchCb(); @@ -251,7 +251,7 @@ namespace Aurora::IO::FS bool NtAsyncFileTransaction::Wait(AuUInt32 timeout) { - auto ret = WaitForSingleObject(this->event_, timeout ? timeout : INFINITE); + auto ret = WaitForSingleObjectEx(this->event_, timeout ? timeout : INFINITE, true); if (ret == WAIT_OBJECT_0) { DispatchCb(); @@ -302,7 +302,7 @@ namespace Aurora::IO::FS handles.push_back(std::static_pointer_cast(file)->GetHandle()); } - auto ret = WaitForMultipleObjects(handles.size(), handles.data(), false, timeout ? timeout : INFINITE); + auto ret = WaitForMultipleObjectsEx(handles.size(), handles.data(), false, timeout ? timeout : INFINITE, TRUE); #if 0 for (const auto &file : files) diff --git a/Source/IO/FS/FileStream.Generic.cpp b/Source/IO/FS/FileStream.Generic.cpp index 17c4e937..5facd4f1 100644 --- a/Source/IO/FS/FileStream.Generic.cpp +++ b/Source/IO/FS/FileStream.Generic.cpp @@ -70,6 +70,12 @@ namespace Aurora::IO::FS { }; + + void WriteEoS() override + { + + } + virtual void GoToEof() = 0; protected: AuUInt64 offset_ = 0; diff --git a/Source/IO/FS/FileStream.NT.cpp b/Source/IO/FS/FileStream.NT.cpp index f693ad3c..26868d35 100644 --- a/Source/IO/FS/FileStream.NT.cpp +++ b/Source/IO/FS/FileStream.NT.cpp @@ -105,7 +105,7 @@ namespace Aurora::IO::FS int blockSize = std::min(kFileCopyBlock, length); - if (!::ReadFile(handle_, &reinterpret_cast(parameters.ptr)[offset], blockSize, &read, NULL)) + if (!::ReadFile(handle_, reinterpret_cast(parameters.ptr) + offset, blockSize, &read, NULL)) { LogWarn("ReadFile IO Error: 0x{:x}, {}", GetLastError(), path_); SysPushErrorIO(); @@ -146,7 +146,7 @@ namespace Aurora::IO::FS int blockSize = std::min(kFileCopyBlock, length); - if (!::WriteFile(handle_, &reinterpret_cast(parameters.ptr)[offset], blockSize, &written, NULL)) + if (!::WriteFile(handle_, reinterpret_cast(parameters.ptr) + offset, blockSize, &written, NULL)) { LogWarn("WriteFileEx IO Error: 0x{:x}, {}", GetLastError(), path_); SysPushErrorIO(); @@ -173,6 +173,17 @@ namespace Aurora::IO::FS return true; } + void WinFileStream::WriteEoS() + { + if (handle_ == INVALID_HANDLE_VALUE) + { + SysPushErrorUninitialized(); + return; + } + + SetEndOfFile(handle_); + } + void WinFileStream::Close() { AuWin32CloseHandle(handle_); diff --git a/Source/IO/FS/FileStream.NT.hpp b/Source/IO/FS/FileStream.NT.hpp index f0fd31dc..365fcf54 100644 --- a/Source/IO/FS/FileStream.NT.hpp +++ b/Source/IO/FS/FileStream.NT.hpp @@ -25,6 +25,7 @@ namespace Aurora::IO::FS bool Write(const Memory::MemoryViewStreamRead & parameters) override; void Close() override; void Flush() override; + void WriteEoS() override; private: diff --git a/Source/Threading/WaitFor.cpp b/Source/Threading/WaitFor.cpp index f72d2da3..73bb0461 100644 --- a/Source/Threading/WaitFor.cpp +++ b/Source/Threading/WaitFor.cpp @@ -23,7 +23,7 @@ namespace Aurora::Threading { - static inline void YieldToSharedCore(long spin) + static void YieldToSharedCore(long spin) { int loops = (1 << spin); while (loops > 0) @@ -315,7 +315,7 @@ namespace Aurora::Threading return reinterpret_cast(handle); }); - auto status = WaitForMultipleObjects(winWaitables.size(), winWaitables.data(), TRUE, timeoutMs ? timeoutMs : INFINITE); + auto status = WaitForMultipleObjectsEx(winWaitables.size(), winWaitables.data(), TRUE, timeoutMs ? timeoutMs : INFINITE, true); SysAssert(status != WAIT_FAILED, "Internal Win32 Error {}", GetLastError()); if (status == WAIT_TIMEOUT)