diff --git a/Aurora.json b/Aurora.json index 155d66da..14b5a755 100644 --- a/Aurora.json +++ b/Aurora.json @@ -1,22 +1,90 @@ { "type": "aurora", "name": "AuroraRuntime", - "dllexport": ["AURORA_ENGINE_KERNEL_EXPORT"], + "dllexport": [ + "AURORA_ENGINE_KERNEL_EXPORT" + ], "dllimport": [], - "impDefines": ["AURORA_ENGINE_KERNEL"], + "impDefines": [ + "AURORA_ENGINE_KERNEL" + ], "staticImpDefines": "AURORA_ENGINE_KERNEL_STATIC", + "clangIgnore": [ + "deprecated-declarations", + "c99-designator", + "reorder-init-list", + "ignored-attributes" + ], "defines": [], - "soft-depends": ["wxwidgets", "glm", "bzip2", "lz4"], - "depends": ["auROXTL", "AuroraInterfaces", "AuroraEnum", "mimalloc", "uuid", "fmt", "json", "ltc", "o1heap", "zstd", "zlib", "mbedtls"], - "include-depends": ["fmt", "uuid", "AuroraInterfaces", "AuroraEnum", "auROXTL"], - "features": ["guess-platform-code"], + "soft-depends": [ + "wxwidgets", + "glm", + "bzip2", + "lz4" + ], + "depends": [ + "auROXTL", + "AuroraInterfaces", + "AuroraEnum", + "mimalloc", + "uuid", + "fmt", + "json", + "ltc", + "o1heap", + "zstd", + "zlib", + "mbedtls" + ], + "include-depends": [ + "fmt", + "uuid", + "AuroraInterfaces", + "AuroraEnum", + "auROXTL" + ], + "features": [ + "guess-platform-code" + ], "linkSources": "Source/Alloc.cpp", "actions": [ { - "filter": {"platforms": "win32"}, + "filter": { + "platforms": "win32" + }, "then": { - "links": ["Bcrypt.lib", "UxTheme.lib", "Aux_ulib.lib", "Dbghelp.lib", "ws2_32.lib", "Ntdll.lib", "Wer.lib", "wintrust.lib"] + "links": [ + "Bcrypt.lib", + "UxTheme.lib", + "Aux_ulib.lib", + "Dbghelp.lib", + "ws2_32.lib", + "Ntdll.lib", + "Wer.lib", + "wintrust.lib" + ] + } + }, + { + "filter": { + "platforms": "linux" + }, + "then": { + "links": [ + "unwind", + "unwind-generic" + ], + "actions": { + "filter": { + "archs": "x86_64" + }, + "then": { + "links": [ + "unwind-x86_64" + ] + } + } } } ] -} +} \ No newline at end of file diff --git a/Include/Aurora/Async/Async.hpp b/Include/Aurora/Async/Async.hpp index 4ce17e65..cc35ef36 100644 --- a/Include/Aurora/Async/Async.hpp +++ b/Include/Aurora/Async/Async.hpp @@ -14,8 +14,8 @@ #include "IThreadPool.hpp" #include "IAsyncApp.hpp" -#include "Jobs.hpp" -#include "Tasks.hpp" +#include "Legacy/Jobs.hpp" +#include "Legacy/Tasks.hpp" namespace Aurora::Async { @@ -43,9 +43,9 @@ namespace Aurora::Async #if !defined(_CPPSHARP) #include "IPCPromises.hpp" - #include "JobFrom.hpp" - #include "TaskFrom.hpp" - #include "WorkPairImpl.hpp" - #include "WorkBasic.hpp" - #include "OldTrash.hpp" + #include "Legacy/JobFrom.hpp" + #include "Legacy/TaskFrom.hpp" + #include "Legacy/WorkPairImpl.hpp" + #include "Legacy/WorkBasic.hpp" + #include "Legacy/OldTrash.hpp" #endif diff --git a/Include/Aurora/Async/IPCPromises.hpp b/Include/Aurora/Async/IPCPromises.hpp index e158d97f..f9801877 100644 --- a/Include/Aurora/Async/IPCPromises.hpp +++ b/Include/Aurora/Async/IPCPromises.hpp @@ -165,9 +165,9 @@ namespace Aurora::Async using FunctionalCall_t = PromiseCallTmpl; using FunctionalResponse_t = PromiseSuccessTmpl; using FunctionalFail_t = PromiseFailTmpl; - using FunctionalResponse_f = FunctionalResponse_t::OnSuccess_f; - using FunctionalFail_f = FunctionalFail_t::OnFailure_f; - using FunctionalDelegate_f = FunctionalCall_t::OnDelegate_f; + using FunctionalResponse_f = typename FunctionalResponse_t::OnSuccess_f; + using FunctionalFail_f = typename FunctionalFail_t::OnFailure_f; + using FunctionalDelegate_f = typename FunctionalCall_t::OnDelegate_f; inline AuSPtr OnSuccessFunctional(const FunctionalResponse_f &in); inline AuSPtr OnSuccessCallback(const AuSPtr &in); diff --git a/Include/Aurora/Async/Legacy/DO NOT REMOVE.txt b/Include/Aurora/Async/Legacy/DO NOT REMOVE.txt new file mode 100755 index 00000000..56e4eb97 --- /dev/null +++ b/Include/Aurora/Async/Legacy/DO NOT REMOVE.txt @@ -0,0 +1,5 @@ + > Deprecated APIs < + +* Wont remove +* Powering old projects +* Sometimes used as shorthands internally \ No newline at end of file diff --git a/Include/Aurora/Async/JobFrom.hpp b/Include/Aurora/Async/Legacy/JobFrom.hpp similarity index 100% rename from Include/Aurora/Async/JobFrom.hpp rename to Include/Aurora/Async/Legacy/JobFrom.hpp diff --git a/Include/Aurora/Async/Jobs.hpp b/Include/Aurora/Async/Legacy/Jobs.hpp similarity index 100% rename from Include/Aurora/Async/Jobs.hpp rename to Include/Aurora/Async/Legacy/Jobs.hpp diff --git a/Include/Aurora/Async/OldTrash.hpp b/Include/Aurora/Async/Legacy/OldTrash.hpp similarity index 100% rename from Include/Aurora/Async/OldTrash.hpp rename to Include/Aurora/Async/Legacy/OldTrash.hpp diff --git a/Include/Aurora/Async/TaskFrom.hpp b/Include/Aurora/Async/Legacy/TaskFrom.hpp similarity index 100% rename from Include/Aurora/Async/TaskFrom.hpp rename to Include/Aurora/Async/Legacy/TaskFrom.hpp diff --git a/Include/Aurora/Async/Tasks.hpp b/Include/Aurora/Async/Legacy/Tasks.hpp similarity index 100% rename from Include/Aurora/Async/Tasks.hpp rename to Include/Aurora/Async/Legacy/Tasks.hpp diff --git a/Include/Aurora/Async/WorkBasic.hpp b/Include/Aurora/Async/Legacy/WorkBasic.hpp similarity index 100% rename from Include/Aurora/Async/WorkBasic.hpp rename to Include/Aurora/Async/Legacy/WorkBasic.hpp diff --git a/Include/Aurora/Async/WorkPairImpl.hpp b/Include/Aurora/Async/Legacy/WorkPairImpl.hpp similarity index 100% rename from Include/Aurora/Async/WorkPairImpl.hpp rename to Include/Aurora/Async/Legacy/WorkPairImpl.hpp diff --git a/Include/Aurora/Console/ConsoleTTY/Buffering.hpp b/Include/Aurora/Console/ConsoleTTY/Buffering.hpp index c44f9aeb..429a4346 100644 --- a/Include/Aurora/Console/ConsoleTTY/Buffering.hpp +++ b/Include/Aurora/Console/ConsoleTTY/Buffering.hpp @@ -9,5 +9,18 @@ namespace Aurora::Console::ConsoleTTY { + /** + * @brief Is in the middle of buffering all stdout writes? + */ + AUKN_SYM bool IsBuffering(); + /** + * @brief Begin stdout buffering + */ + AUKN_SYM void BeginBuffering(); + + /** + * @brief Flip framebuffer + */ + AUKN_SYM bool EndBuffering(); } \ No newline at end of file diff --git a/Source/Compression/Compressors/BZip2Compressor.hpp b/Source/Compression/Compressors/BZip2Compressor.hpp index 8ad832a9..fc9a3476 100644 --- a/Source/Compression/Compressors/BZip2Compressor.hpp +++ b/Source/Compression/Compressors/BZip2Compressor.hpp @@ -45,7 +45,7 @@ namespace Aurora::Compression } } - bool Init(const AuSPtr &reader) + bool Init(const AuSPtr &reader) override { this->reader_ = reader; diff --git a/Source/Compression/Compressors/BZip2Decompressor.hpp b/Source/Compression/Compressors/BZip2Decompressor.hpp index c959fdb1..c5b9fa56 100644 --- a/Source/Compression/Compressors/BZip2Decompressor.hpp +++ b/Source/Compression/Compressors/BZip2Decompressor.hpp @@ -45,7 +45,7 @@ namespace Aurora::Compression } } - bool Init(const AuSPtr &reader) + bool Init(const AuSPtr &reader) override { this->reader_ = reader; diff --git a/Source/Compression/Compressors/DeflateCompressor.hpp b/Source/Compression/Compressors/DeflateCompressor.hpp index 08aa2153..ea8b660f 100644 --- a/Source/Compression/Compressors/DeflateCompressor.hpp +++ b/Source/Compression/Compressors/DeflateCompressor.hpp @@ -27,7 +27,7 @@ namespace Aurora::Compression } } - bool Init(const AuSPtr &reader) + bool Init(const AuSPtr &reader) override { this->reader_ = reader; diff --git a/Source/Compression/Compressors/DeflateDecompressor.hpp b/Source/Compression/Compressors/DeflateDecompressor.hpp index 9a3d9470..92ad47d8 100644 --- a/Source/Compression/Compressors/DeflateDecompressor.hpp +++ b/Source/Compression/Compressors/DeflateDecompressor.hpp @@ -26,7 +26,7 @@ namespace Aurora::Compression } } - bool Init(const AuSPtr &reader) + bool Init(const AuSPtr &reader) override { int ret; this->reader_ = reader; diff --git a/Source/Compression/Compressors/LZ4Compressor.hpp b/Source/Compression/Compressors/LZ4Compressor.hpp index 8f6b53c8..4a9b3e3d 100644 --- a/Source/Compression/Compressors/LZ4Compressor.hpp +++ b/Source/Compression/Compressors/LZ4Compressor.hpp @@ -33,7 +33,7 @@ namespace Aurora::Compression } - bool Init(const AuSPtr &reader) + bool Init(const AuSPtr &reader) override { this->reader_ = reader; diff --git a/Source/Compression/Compressors/LZ4Decompressor.hpp b/Source/Compression/Compressors/LZ4Decompressor.hpp index 60ed3c1a..c2ad01e9 100644 --- a/Source/Compression/Compressors/LZ4Decompressor.hpp +++ b/Source/Compression/Compressors/LZ4Decompressor.hpp @@ -34,7 +34,7 @@ namespace Aurora::Compression } } - bool Init(const AuSPtr &reader) + bool Init(const AuSPtr &reader) override { this->reader_ = reader; diff --git a/Source/Compression/Compressors/ZSTDCompressor.hpp b/Source/Compression/Compressors/ZSTDCompressor.hpp index e9e7de3d..7176129d 100644 --- a/Source/Compression/Compressors/ZSTDCompressor.hpp +++ b/Source/Compression/Compressors/ZSTDCompressor.hpp @@ -26,7 +26,7 @@ namespace Aurora::Compression } } - bool Init(const AuSPtr &reader) + bool Init(const AuSPtr &reader) override { size_t ret; diff --git a/Source/Compression/Compressors/ZSTDDecompressor.hpp b/Source/Compression/Compressors/ZSTDDecompressor.hpp index 90428477..4b5ebf0b 100644 --- a/Source/Compression/Compressors/ZSTDDecompressor.hpp +++ b/Source/Compression/Compressors/ZSTDDecompressor.hpp @@ -26,7 +26,7 @@ namespace Aurora::Compression } } - bool Init(const AuSPtr &reader) + bool Init(const AuSPtr &reader) override { this->reader_ = reader; this->dctx_ = ZSTD_createDCtx(); diff --git a/Source/Console/ConsoleStd/ConsoleStd.cpp b/Source/Console/ConsoleStd/ConsoleStd.cpp index 06bbf3b1..9ef5708c 100755 --- a/Source/Console/ConsoleStd/ConsoleStd.cpp +++ b/Source/Console/ConsoleStd/ConsoleStd.cpp @@ -104,6 +104,7 @@ namespace Aurora::Console::ConsoleStd //static AuThreadPrimitives::MutexUnique_t gRingLock = AuThreadPrimitives::MutexUnique(); static AuThreadPrimitives::SpinLock gRingLock;// = AuThreadPrimitives::MutexUnique(); + static bool gBufferMode {}; #if defined(AURORA_IS_MODERNNT_DERIVED) @@ -371,6 +372,7 @@ namespace Aurora::Console::ConsoleStd bool EnterNoncanonicalMode() { + return false; } void LeaveNoncanonicalMode() @@ -399,7 +401,7 @@ namespace Aurora::Console::ConsoleStd return dwType == FILE_TYPE_CHAR; #else - return IsStdOutTTY(stdout); + return IsStdOutTTY(STDOUT_FILENO); #endif } @@ -637,6 +639,11 @@ namespace Aurora::Console::ConsoleStd static AuUInt32 WriteStdOutBlocking(const void *data, AuUInt32 length) { + if (gBufferMode) + { + return gStdoutBuffer.Write(data, length); + } + if (!IS_STREAM_HANDLE_VALID(gOutputStream)) { return 0; @@ -666,6 +673,11 @@ namespace Aurora::Console::ConsoleStd void FlushStdOutNb() { + if (gBufferMode) + { + return; + } + AuUInt32 written {}; written = WriteStdOutBlocking(gStdoutBuffer.begin(), gStdoutBuffer.size()); gStdoutBuffer.clear(); @@ -685,21 +697,20 @@ namespace Aurora::Console::ConsoleStd { AU_LOCK_GUARD(gRingLock); - FlushStdOutNb(); - return WriteStdOutBlocking(data, length); } void Lock() { - gRingLock.Lock(); + AU_LOCK_GUARD(gRingLock); + gBufferMode = true; } void Unlock() { + AU_LOCK_GUARD(gRingLock); + gBufferMode = false; FlushStdOutNb(); - - gRingLock.Unlock(); } AuUInt32 WriteStdOutNonBlocking(const void *data, AuUInt32 length) diff --git a/Source/Console/ConsoleStd/ConsoleStd.hpp b/Source/Console/ConsoleStd/ConsoleStd.hpp index 530ba0dc..39fa8ecc 100644 --- a/Source/Console/ConsoleStd/ConsoleStd.hpp +++ b/Source/Console/ConsoleStd/ConsoleStd.hpp @@ -21,15 +21,11 @@ namespace Aurora::Console::ConsoleStd void Lock(); void Unlock(); - AuUInt32 WriteStdOutNonBlocking(const void *data, AuUInt32 length); - void FlushStdOutNb(); AuUInt32 ReadStdIn(void *data, AuUInt32 length); AuUInt32 WriteStdOut(const void *data, AuUInt32 length); void WriteStdOut(AuUInt8 level, const ConsoleMessage &msg); - - #if defined(AURORA_IS_MODERNNT_DERIVED) void ProcessCanonical(HANDLE h); diff --git a/Source/Console/ConsoleTTY/ConsoleTTY.Unix.cpp b/Source/Console/ConsoleTTY/ConsoleTTY.Unix.cpp index cf93e3ca..9aadd202 100644 --- a/Source/Console/ConsoleTTY/ConsoleTTY.Unix.cpp +++ b/Source/Console/ConsoleTTY/ConsoleTTY.Unix.cpp @@ -24,14 +24,12 @@ namespace Aurora::Console::ConsoleTTY void BeginBuffering() { - return; ConsoleStd::Lock(); gIsBuffering = true; } bool EndBuffering() { - return true; ConsoleStd::Unlock(); gIsBuffering = false; //TODO (Reece): Was signal handler called? @@ -45,9 +43,7 @@ namespace Aurora::Console::ConsoleTTY return; } - auto written = gIsBuffering ? ConsoleStd::WriteStdOutNonBlocking(in.data(), in.size()) - : ConsoleStd::WriteStdOutBlocking2(in.data(), in.size()); - + auto written = ConsoleStd::WriteStdOutBlocking2(in.data(), in.size()); SysAssert(written == in.size(), "TTY Buffer Full"); } @@ -104,8 +100,7 @@ namespace Aurora::Console::ConsoleTTY return 0; } - return gIsBuffering ? ConsoleStd::WriteStdOutNonBlocking(buffer, length) - : ConsoleStd::WriteStdOutBlocking2(buffer, length); + return ConsoleStd::WriteStdOutBlocking2(buffer, length); } AUKN_SYM void TTYWrite(const char *string, EAnsiColor fgColor, EAnsiColor bgColor) @@ -175,14 +170,7 @@ namespace Aurora::Console::ConsoleTTY static void ForceFlush() { - if (gIsBuffering) - { - ConsoleStd::FlushStdOutNb(); - } - else - { - ConsoleStd::Flush(); - } + ConsoleStd::Flush(); } AUKN_SYM void TTYStorePos() diff --git a/Source/Console/ConsoleTTY/ConsoleTTY.cpp b/Source/Console/ConsoleTTY/ConsoleTTY.cpp index 64fea896..41a02669 100644 --- a/Source/Console/ConsoleTTY/ConsoleTTY.cpp +++ b/Source/Console/ConsoleTTY/ConsoleTTY.cpp @@ -1034,7 +1034,7 @@ namespace Aurora::Console::ConsoleTTY void TTYConsole::BlankLine(int Y, bool borders) { TTYSetPos({0, Y}); - TTYClearLine(); + TTYClearLine(EAnsiColor::eReset); BlankBordersLine(Y); } diff --git a/Source/Console/ConsoleTTY/ConsoleTTY.hpp b/Source/Console/ConsoleTTY/ConsoleTTY.hpp index 6d1d82ee..bc69e9bc 100644 --- a/Source/Console/ConsoleTTY/ConsoleTTY.hpp +++ b/Source/Console/ConsoleTTY/ConsoleTTY.hpp @@ -13,7 +13,7 @@ namespace Aurora::Console::ConsoleTTY struct TTYConsole : ITTYConsole { - void BufferMessage(const AuConsole::ConsoleMessage &msg); + void BufferMessage(const AuConsole::ConsoleMessage &msg) override; void Pump(); void PumpHistory(); @@ -46,7 +46,7 @@ namespace Aurora::Console::ConsoleTTY bool RegenerateBuffer(bool resChanged, bool &redrawBox); - bool NoncanonicalMode(); + bool NoncanonicalMode() override; void NoncanonicalTick(); void NoncanonicalSetCursor(); void NoncanonicalOnString(const AuString &input); @@ -194,7 +194,7 @@ namespace Aurora::Console::ConsoleTTY struct AlignedString { AuString str; - ETTYAlign align; + ETTYAlign align {}; }; AuString tempMemory; @@ -216,8 +216,8 @@ namespace Aurora::Console::ConsoleTTY bool bLeftBorder {true}; bool bTopBorder {true}; - bool bShouldShowBorders; - bool bShowingBorders; + bool bShouldShowBorders {}; + bool bShowingBorders {}; bool IsShowingHintLine(); diff --git a/Source/Debug/Debug.cpp b/Source/Debug/Debug.cpp index 72598063..c1427a80 100644 --- a/Source/Debug/Debug.cpp +++ b/Source/Debug/Debug.cpp @@ -15,6 +15,10 @@ #include "Stack.Win32.hpp" #endif +#if defined(AURORA_IS_LINUX_DERIVED) + #include "Stack.Unix.hpp" +#endif + namespace Aurora::Debug { static thread_local AuUInt32 tlsLastBackTrace = 0xFFFFFFFF; @@ -208,7 +212,7 @@ namespace Aurora::Debug AUKN_SYM StackTrace GetStackTrace() { - #if defined(AURORA_PLATFORM_WIN32) + #if defined(AURORA_PLATFORM_WIN32) || defined(AURORA_IS_LINUX_DERIVED) return PlatformWalkCallStack(); #else return {}; diff --git a/Source/Debug/ExceptionWatcher.Unix.cpp b/Source/Debug/ExceptionWatcher.Unix.cpp index fa62ecdd..4f81518a 100644 --- a/Source/Debug/ExceptionWatcher.Unix.cpp +++ b/Source/Debug/ExceptionWatcher.Unix.cpp @@ -14,4 +14,10 @@ namespace Aurora::Debug { } + + + void InitUNIX() + { + + } } \ No newline at end of file diff --git a/Source/Debug/Stack.Unix.cpp b/Source/Debug/Stack.Unix.cpp index d8f92f31..64990b09 100644 --- a/Source/Debug/Stack.Unix.cpp +++ b/Source/Debug/Stack.Unix.cpp @@ -5,3 +5,121 @@ Date: 2022-1-26 Author: Reece ***/ +#include +#include "Stack.hpp" +#include "Stack.Unix.hpp" +#include +#include + +namespace Aurora::Debug +{ + static void TryComplete(StackTraceEntry &entry) + { + + } + + static StackTrace DumpContext(unw_context_t *uc) + { + StackTrace ret; + + unw_cursor_t cursor; + unw_word_t ip; + + ::unw_init_local(&cursor, uc); + + while (::unw_step(&cursor) > 0) + { + StackTraceEntry entry; + + ::unw_get_reg(&cursor, UNW_REG_IP, &ip); + + // module + { + unw_word_t off; + char procName[512]; + + if (unw_get_proc_name(&cursor, procName, AuArraySize(procName), &off) == 0) + { + AuString str; + str = AuString(procName, strlen(procName)); + str += fmt::format("+0x{:x}", off); + entry.label = str; + } + } + + { + Dl_info dlinfo; + AuSInt originalIP {}; + AuUInt moduleAddress {}; + + const char *dllPathName {}; + + if (::dladdr((const void *)ip, &dlinfo)) + { + dllPathName = dlinfo.dli_fname; + moduleAddress = (AuUInt)dlinfo.dli_fbase; + originalIP = (AuUInt)ip - moduleAddress; + } + + entry.address = ip; + entry.relAddress = originalIP; + + if (dllPathName) + { + entry.module = dllPathName; + } + } + + AuTryInsert(ret, entry); + } + + return ret; + } + + StackTrace DumpContextPlatform(ucontext_t &uc) + { + // VALID: + // Linux: https://github.com/libunwind/libunwind/blob/3be832395426b72248969247a4a66e3c3623578d/include/libunwind-x86.h#L170 + + // ??? + // MACOS: https://github.com/JuliaLang/libosxunwind/blob/master/include/libunwind.h#L57 + return DumpContext((unw_context_t *)&uc); + } + + StackTrace PlatformWalkCallStack() + { + #if 0 + StackTrace ret; + void *ips[1024]; + + int count = ::backtrace(ips, AuArraySize(ips)); + + auto messages = ::backtrace_symbols(ips, count); + if (!messages) + { + return {}; + } + + for (int i = 0; i < count; i++) + { + StackTraceEntry entry; + + entry.address = AuUInt64(ips[i]); + entry.label = AuUInt64(messages[i]); + + TryComplete(entry); + + AuTryInsert(ret, entry); + } + + free(messages); + + return ret; + #endif + + ::unw_context_t uc; + ::unw_getcontext(&uc); + + return DumpContext(&uc); + } +} \ No newline at end of file diff --git a/Source/Debug/Stack.Unix.hpp b/Source/Debug/Stack.Unix.hpp index f20f67b8..6e01b68c 100644 --- a/Source/Debug/Stack.Unix.hpp +++ b/Source/Debug/Stack.Unix.hpp @@ -7,3 +7,11 @@ ***/ #pragma once +#include + +namespace Aurora::Debug +{ + StackTrace DumpContext(ucontext_t &uc); + + StackTrace PlatformWalkCallStack(); +} \ No newline at end of file diff --git a/Source/Exit/Exit.Unix.cpp b/Source/Exit/Exit.Unix.cpp index be5280ea..7b7ac550 100644 --- a/Source/Exit/Exit.Unix.cpp +++ b/Source/Exit/Exit.Unix.cpp @@ -41,7 +41,7 @@ namespace Aurora::Exit sigemptyset(&action.sa_mask); sigaction(SIGINT, &action, nullptr); - sigaction(SIGTERM, &action, nullptr); + //sigaction(SIGTERM, &action, nullptr); } void DeinitUnix() @@ -54,6 +54,6 @@ namespace Aurora::Exit sigemptyset(&action.sa_mask); sigaction(SIGINT, &action, nullptr); - sigaction(SIGTERM, &action, nullptr); + //sigaction(SIGTERM, &action, nullptr); } } \ No newline at end of file diff --git a/Source/Exit/Exit.cpp b/Source/Exit/Exit.cpp index 414eeaba..d8895cf7 100644 --- a/Source/Exit/Exit.cpp +++ b/Source/Exit/Exit.cpp @@ -115,6 +115,7 @@ namespace Aurora::Exit } else { + AuLogInfo("Process Exiting"); Process::Exit(0); } } diff --git a/Source/HWInfo/CpuInfo.Linux.cpp b/Source/HWInfo/CpuInfo.Linux.cpp index dc7ad6a8..57315c0c 100644 --- a/Source/HWInfo/CpuInfo.Linux.cpp +++ b/Source/HWInfo/CpuInfo.Linux.cpp @@ -19,7 +19,7 @@ namespace Aurora::HWInfo static AuUInt32 ReadUInt(const AuString &path) { AuString contents; - if (AuIOFS::ReadString(path, contents)) + if (!AuIOFS::ReadString(path, contents)) { return 0; } diff --git a/Source/IO/FS/FS.Unix.cpp b/Source/IO/FS/FS.Unix.cpp index b0b498dd..8b5ac797 100755 --- a/Source/IO/FS/FS.Unix.cpp +++ b/Source/IO/FS/FS.Unix.cpp @@ -13,6 +13,7 @@ #if !defined(_AURUNTIME_GENERICFS) #include +#include #include #include #include @@ -28,14 +29,164 @@ namespace Aurora::IO::FS return mkdir(path.c_str(), 0775) == 0; } + struct ReadDirStructure : IReadDir + { + DIR *pDIR {}; + struct dirent *pDE {}; + bool bFirstTick { true }; + bool bDead { false }; + StatEx stat; + AuString sPath; + bool bFast {}; + + ~ReadDirStructure() + { + if (this->pDIR) + { + ::closedir(this->pDIR); + } + } + + virtual StatEx *Next() override + { + bool bTryAgain {}; + + if (this->bDead) + { + return {}; + } + + do + { + if (!(this->pDE = ::readdir(this->pDIR))) + { + this->bDead = true; + return {}; + } + + if (this->pDE->d_name == AuString(".") || + this->pDE->d_name == AuString("..")) + { + bTryAgain = true; + continue; + } + + stat.exists = true; + + stat.fileName = this->pDE->d_name; + + if (stat.fileName.empty()) + { + bTryAgain = true; + continue; + } + + stat.path = NormalizePathRet(this->sPath + stat.fileName); + + if (this->bFast) + { + // nvm wont work. still need the is type dir/file flags + // return &stat; + } + + if (!StatFile(stat.path.c_str(), stat)) + { + bTryAgain = true; + } + + } + while (AuExchange(bTryAgain, false)); + + return &stat; + } + }; + + static AuSPtr ReadDirEx(const AuString &string, bool bFast) + { + auto pObj = AuMakeShared(); + if (!pObj) + { + SysPushErrorMem(); + return {}; + } + + pObj->bFast = bFast; + + if (!AuIOFS::NormalizePath(pObj->sPath, string)) + { + SysPushErrorMem(); + return {}; + } + + if (!AuTryInsert(pObj->sPath, '/')) + { + SysPushErrorMem(); + return {}; + } + + pObj->pDIR = ::opendir(pObj->sPath.c_str()); + if (!pObj->pDIR) + { + SysPushErrorIO(); + return {}; + } + + return pObj; + } + + AUKN_SYM AuSPtr ReadDir(const AuString &string) + { + return ReadDirEx(string, false); + } + AUKN_SYM bool FilesInDirectory(const AuString &string, AuList &files) { - return IterateDirEntriesSTL(string, true, files); + auto itr = ReadDirEx(string, true); + if (!itr) + { + return false; + } + + // SECURITY(): if next fails, its indistinguishable from end of file list, and will return true. it kinda sucks + while (auto stat = itr->Next()) + { + if (!stat->existsFile) + { + continue; + } + + if (!AuTryInsert(files, stat->fileName)) + { + return false; + } + } + + return true; } AUKN_SYM bool DirsInDirectory(const AuString &string, AuList &dirs) { - return IterateDirEntriesSTL(string, false, dirs); + auto itr = ReadDirEx(string, true); + if (!itr) + { + return false; + } + + // SECURITY(): if next fails, its indistinguishable from end of file list, and will return true. it kinda sucks + while (auto stat = itr->Next()) + { + if (!stat->existsDirectory) + { + continue; + } + + if (!AuTryInsert(dirs, stat->fileName)) + { + return false; + } + } + + return true; } AUKN_SYM bool WriteFile(const AuString &path, const Memory::MemoryViewRead &blob) @@ -231,7 +382,7 @@ namespace Aurora::IO::FS { if (ENOENT != errno) { - LogWarn("Critical IO error while stating file (errno: {}, path: {})", errno, path); + AuLogWarn("Critical IO error while stating file (errno: {}, path: {})", errno, path); } return false; } @@ -243,7 +394,7 @@ namespace Aurora::IO::FS if (!stat.exists) { - LogWarn("Missing attribute type in stat mode {} (of path {})", s.st_mode, path); + AuLogWarn("Missing attribute type in stat mode {} (of path {})", s.st_mode, path); return false; } diff --git a/Source/IO/FS/FS.hpp b/Source/IO/FS/FS.hpp index c955d8aa..4c3583e5 100644 --- a/Source/IO/FS/FS.hpp +++ b/Source/IO/FS/FS.hpp @@ -118,38 +118,5 @@ namespace Aurora::IO::FS } } - static bool IterateDirEntriesSTL(const AuString &path, bool filesOnly, AuList &patches) - { - #if defined(HAS_STD_FS) - auto normalizedPath = NormalizePathRet(path); - try - { - for (const auto &entry : std::filesystem::directory_iterator(normalizedPath)) - { - auto cpath = entry.path(); - - if (filesOnly && !std::filesystem::is_regular_file(cpath)) - continue; - - if (!filesOnly && !std::filesystem::is_directory(cpath)) - continue; - - AuString path = cpath.string(); - patches.push_back(path.substr(path.find_last_of(kPathSplitter) + 1)); - } - - return true; - } - catch (...) - { - Debug::PrintError(); - Logging::LogWarn("IO Error, couldn't iterate path: {}", normalizedPath); - return false; - } - #endif - - return false; - } - void InitResources(); } \ No newline at end of file diff --git a/Source/IO/FS/FileAdvisory.Unix.cpp b/Source/IO/FS/FileAdvisory.Unix.cpp index be0938c3..03402af2 100644 --- a/Source/IO/FS/FileAdvisory.Unix.cpp +++ b/Source/IO/FS/FileAdvisory.Unix.cpp @@ -14,6 +14,7 @@ namespace Aurora::IO::FS { bool ApplyDumbAdvisoryLock(int fd, EFileAdvisoryLockLevel level) { + #if !defined(AURORA_IS_LINUX_DERIVED) int operation = LOCK_NB; switch (level) @@ -29,6 +30,60 @@ namespace Aurora::IO::FS break; } - return flock(fd, operation) == 0; + // Assume: + // "Furthermore, the lock is release either by an explicit LOCK_UN + // operation on any of these duplicate file descriptors, or when + // all such file descriptors have been closed" + + return ::flock(fd, operation) == 0; + #else + // Linux + int lease {}; + + switch (level) + { + case EFileAdvisoryLockLevel::eEnumCount: + case EFileAdvisoryLockLevel::eNoSafety: + return true; + case EFileAdvisoryLockLevel::eBlockWrite: + lease = F_RDLCK; + break; + case EFileAdvisoryLockLevel::eBlockReadWrite: + lease = F_RDLCK; + break; + } + + // Ignore warning bc idc + // I assume c++ compilers under posix land allow for struct init the c way + struct flock lck = + { + .l_whence = SEEK_SET, + .l_start = 0, + .l_len = 0, + .l_type = lease + }; + + // Assume this is true: + // * If a process closes any file descriptor referring to a file, + // then all of the process's locks on that file are released, + // regardless of the file descriptor(s) on which the locks were + // obtained. This is bad: it means that a process can lose its + // locks on a file such as /etc/passwd or /etc/mtab when for some + // reason a library function decides to open, read, and close the + // same file. + // [...] + // + // Open file description locks solve both of these problems. + // + // OFD's description implies it inherits non-ofd behaviour + // I wanted to confirm a l_len zero would work to lock all contents, + // even on expansion of the file. The docs didn't mention anything; + // however, I don't really see any real difference len processing in + // the kernel. Furthermore, I saw the kernels implementation checking + // for MAX_OFFSET of int type (-1) before overloading l_len with zero. + // + // I assume this will work. Linux locking is trash. + return ::fcntl(fd, F_OFD_SETLK, &lck) == 0; + #endif } } \ No newline at end of file diff --git a/Source/IO/IOAdapterAsyncStream.cpp b/Source/IO/IOAdapterAsyncStream.cpp index 60610678..814e69ab 100644 --- a/Source/IO/IOAdapterAsyncStream.cpp +++ b/Source/IO/IOAdapterAsyncStream.cpp @@ -80,11 +80,11 @@ namespace Aurora::IO void ReserveBuffer(AuUInt length) override; - AuUInt GetReadOffset(); - AuUInt SetReadOffset(AuUInt offset); + AuUInt GetReadOffset() override; + AuUInt SetReadOffset(AuUInt offset) override; - AuUInt GetWriteOffset(); - AuUInt SetWriteOffset(AuUInt offset); + AuUInt GetWriteOffset() override; + AuUInt SetWriteOffset(AuUInt offset) override; bool asyncActive {}; AuUInt readOffset {}; diff --git a/Source/IO/IOProcessor.hpp b/Source/IO/IOProcessor.hpp index 431a46fa..6fe3af8d 100644 --- a/Source/IO/IOProcessor.hpp +++ b/Source/IO/IOProcessor.hpp @@ -26,7 +26,7 @@ namespace Aurora::IO AuUInt32 TryTick() override; AuUInt32 RunTick() override; - AuUInt32 TickFor(const AuSPtr &ioEvent); + AuUInt32 TickFor(const AuSPtr &ioEvent) override; bool TickForRegister(const AuSPtr &ioEvent); void TickForHack(const AuSPtr &ioEvent); diff --git a/Source/IO/IOSleep.Linux.cpp b/Source/IO/IOSleep.Linux.cpp index af6503cd..f3b6aff4 100644 --- a/Source/IO/IOSleep.Linux.cpp +++ b/Source/IO/IOSleep.Linux.cpp @@ -59,7 +59,6 @@ namespace Aurora::IO AUKN_SYM bool IOYield() { - AuLogWarn("TODO"); - return false; + return UNIX::LinuxOverlappedYield(); } } \ No newline at end of file diff --git a/Source/IO/IPC/IPCHandle.cpp b/Source/IO/IPC/IPCHandle.cpp index 34212fee..09c7d045 100644 --- a/Source/IO/IPC/IPCHandle.cpp +++ b/Source/IO/IPC/IPCHandle.cpp @@ -65,7 +65,7 @@ namespace Aurora::IO::IPC return this->values[0].subtype == type; } - bool IPCHandle::PushId(EIPCHandleType type, IPCToken &token) + bool IPCHandle::PushId(EIPCHandleType type, const IPCToken &token) { IPCValue val; val.subtype = type; @@ -157,6 +157,7 @@ namespace Aurora::IO::IPC int stringOffset {}; int count {}; + IPCHeader headerZero; while (in.size() > (stringOffset + 2)) { int index = count++; @@ -172,6 +173,11 @@ namespace Aurora::IO::IPC this->pid = nextInt; } + if (index == 0) + { + headerZero = header; + } + auto readIPC = [&](IPCHeader header, IPCValue &value) { value.subtype = (EIPCHandleType)header.bmType; @@ -256,7 +262,7 @@ namespace Aurora::IO::IPC IPCHeader header; header.bmArray = index == 0 ? this->values.size() : 0; - header.bmHasPid = index == 0 ? this->pid : 0; + header.bmHasPid = index == 0 ? (this->pid ? 1 : 0) : 0; header.bmType = (AuUInt8)ipcValue.subtype; header.bmHasWord = (AuUInt8)(ipcValue.token.word ? 1 : 0); @@ -308,5 +314,10 @@ namespace Aurora::IO::IPC { return this->pid; } + + pid_t IPCToken::ToUnixPid() const + { + return this->pid; + } #endif } \ No newline at end of file diff --git a/Source/IO/IPC/IPCHandle.hpp b/Source/IO/IPC/IPCHandle.hpp index a67b644f..7c745f6f 100644 --- a/Source/IO/IPC/IPCHandle.hpp +++ b/Source/IO/IPC/IPCHandle.hpp @@ -15,7 +15,8 @@ namespace Aurora::IO::IPC eIPCSharedFd, eIPCPrimitiveSemaphore, eIPCPrimitiveMutex, - eIPCPrimitiveEvent + eIPCPrimitiveEvent, + eIPCPipeEnd )); struct IPCToken @@ -37,6 +38,10 @@ namespace Aurora::IO::IPC AuString ToNTPath() const; AuUInt32 ToUnixServerCookie() const; + +#if defined(AURORA_IS_POSIX_DERIVED) + pid_t ToUnixPid() const; +#endif }; struct IPCValue @@ -70,7 +75,7 @@ namespace Aurora::IO::IPC IPCHandle(); bool IsTopEq(EIPCHandleType type) const; - bool PushId(EIPCHandleType type, IPCToken &token); + bool PushId(EIPCHandleType type, const IPCToken &token); IPCValue *GetToken(EIPCHandleType type, int id); diff --git a/Source/IO/IPC/IPCMemory.NT.cpp b/Source/IO/IPC/IPCMemory.NT.cpp index 5048683e..9159e281 100644 --- a/Source/IO/IPC/IPCMemory.NT.cpp +++ b/Source/IO/IPC/IPCMemory.NT.cpp @@ -10,32 +10,11 @@ #include "IPCHandle.hpp" #include "IPCMemory.NT.hpp" -#include -#include - namespace Aurora::IO::IPC { ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Shared memory ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - - struct IPCSharedMemoryImpl : IPCSharedMemory - { - IPCSharedMemoryImpl(HANDLE handle, void *ptr, const IPC::IPCHandle &ipcHandle); - ~IPCSharedMemoryImpl(); - - virtual Memory::MemoryViewWrite GetMemory() override; - virtual AuUInt GetLength() override; - - virtual AuString ExportToString() override; - - private: - IPC::IPCHandle ipcHandle_; - bool owns_; - HANDLE handle_{}; - void *base_{}; - AuUInt len_ {}; - }; IPCSharedMemoryImpl::IPCSharedMemoryImpl(HANDLE handle, void *ptr, const IPC::IPCHandle &ipcHandle) : base_(ptr), len_(ipcHandle.values[0].token.word), handle_(handle), ipcHandle_(ipcHandle) diff --git a/Source/IO/IPC/IPCMemory.NT.hpp b/Source/IO/IPC/IPCMemory.NT.hpp index 79749f40..9bb66a5d 100644 --- a/Source/IO/IPC/IPCMemory.NT.hpp +++ b/Source/IO/IPC/IPCMemory.NT.hpp @@ -7,7 +7,26 @@ ***/ #pragma once +#include +#include + namespace Aurora::IO::IPC { + struct IPCSharedMemoryImpl : IPCSharedMemory + { + IPCSharedMemoryImpl(HANDLE handle, void *ptr, const IPC::IPCHandle &ipcHandle); + ~IPCSharedMemoryImpl(); + virtual Memory::MemoryViewWrite GetMemory() override; + virtual AuUInt GetLength() override; + + virtual AuString ExportToString() override; + + private: + IPC::IPCHandle ipcHandle_; + bool owns_; + HANDLE handle_{}; + void *base_{}; + AuUInt len_ {}; + }; } \ No newline at end of file diff --git a/Source/IO/IPC/IPCMemory.Unix.cpp b/Source/IO/IPC/IPCMemory.Unix.cpp index 2807285c..364d56bf 100644 --- a/Source/IO/IPC/IPCMemory.Unix.cpp +++ b/Source/IO/IPC/IPCMemory.Unix.cpp @@ -10,38 +10,21 @@ #include "IPCHandle.hpp" #include "IPCMemory.Unix.hpp" -#include -#include - #include #include /* For mode constants */ #include /* For O_* constants */ +#if defined(AURORA_IS_LINUX_DERIVED) + #include "IPCMutexFutex.Linux.hpp" /* For import */ +#endif + namespace Aurora::IO::IPC { ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Shared memory ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - - struct IPCSharedMemoryImpl : IPCSharedMemory - { - IPCSharedMemoryImpl(int fd, void *ptr, const IPC::IPCHandle &handle, bool owns); - ~IPCSharedMemoryImpl(); - virtual Memory::MemoryViewWrite GetMemory() override; - virtual AuUInt GetLength() override; - - virtual AuString ExportToString() override; - - private: - IPC::IPCHandle handle_; - bool owns_; - int fd_{}; - void *base_{}; - AuUInt len_ {}; - }; - - static AuString GetServerPath(const IPC::IPCHandle &handle) + static AuString GetServerPath(const IPC::IPCToken &handle) { AuString path; path += "/AURORA_"; @@ -52,7 +35,7 @@ namespace Aurora::IO::IPC } IPCSharedMemoryImpl::IPCSharedMemoryImpl(int fd, void *ptr, const IPC::IPCHandle &handle, bool owns) : - fd_(fd), base_(ptr), len_(handle.word), owns_(owns), handle_(handle) + fd_(fd), base_(ptr), len_(handle.values[0].token.word), owns_(owns), handle_(handle) { } @@ -89,9 +72,14 @@ namespace Aurora::IO::IPC AUKN_SYM AuSPtr NewSharedMemory(AuUInt length) { IPC::IPCHandle handle; - handle.NewId(length); + IPC::IPCToken token; + token.pid = handle.pid; + token.word = length; + token.NewId(); - auto path = GetServerPath(handle); + handle.PushId(EIPCHandleType::eIPCMemory, token); + + auto path = GetServerPath(token); int fd = ::shm_open(path.c_str(), O_RDWR | O_CREAT, S_IRUSR | S_IWUSR); if (fd == -1) { @@ -126,17 +114,9 @@ namespace Aurora::IO::IPC return object; } - AUKN_SYM AuSPtr ImportSharedMemory(const AuString &handleString) + AuSPtr ImportSharedMemoryEx(const IPCToken &token) { - IPC::IPCHandle handle; - - if (!handle.FromString(handleString)) - { - SysPushErrorParseError(); - return {}; - } - - auto path = GetServerPath(handle); + auto path = GetServerPath(token); int fd = ::shm_open(path.c_str(), O_RDWR, S_IRUSR | S_IWUSR); if (fd == -1) { @@ -144,7 +124,7 @@ namespace Aurora::IO::IPC return {}; } - auto map = ::mmap(nullptr, handle.word, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); + auto map = ::mmap(nullptr, token.word, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); if (map == MAP_FAILED) { SysPushErrorIO(); @@ -152,15 +132,38 @@ namespace Aurora::IO::IPC return {}; } + IPC::IPCHandle handle; + handle.PushId(EIPCHandleType::eIPCMemory, token); + auto object = AuMakeShared(fd, map, handle, false); if (!object) { SysPushErrorMem(); - ::munmap(map, handle.word); + ::munmap(map, token.word); ::close(fd); return {}; } return object; } + + AUKN_SYM AuSPtr ImportSharedMemory(const AuString &handleString) + { + IPC::IPCHandle handle; + + if (!handle.FromString(handleString)) + { + SysPushErrorParseError("Invalid handle: {}", handleString); + return {}; + } + + auto val = handle.GetToken(IPC::EIPCHandleType::eIPCMemory, 0); + if (!val) + { + SysPushErrorParseError("Invalid handle: {}", handleString); + return {}; + } + + return ImportSharedMemoryEx(val->token); + } } \ No newline at end of file diff --git a/Source/IO/IPC/IPCMemory.Unix.hpp b/Source/IO/IPC/IPCMemory.Unix.hpp index 1866b02e..122afd5a 100644 --- a/Source/IO/IPC/IPCMemory.Unix.hpp +++ b/Source/IO/IPC/IPCMemory.Unix.hpp @@ -7,7 +7,28 @@ ***/ #pragma once +#include +#include + namespace Aurora::IO::IPC { + struct IPCSharedMemoryImpl : IPCSharedMemory + { + IPCSharedMemoryImpl(int fd, void *ptr, const IPC::IPCHandle &handle, bool owns); + ~IPCSharedMemoryImpl(); + virtual Memory::MemoryViewWrite GetMemory() override; + virtual AuUInt GetLength() override; + + virtual AuString ExportToString() override; + + IPC::IPCHandle handle_; + private: + bool owns_; + int fd_{}; + void *base_{}; + AuUInt len_ {}; + }; + + AuSPtr ImportSharedMemoryEx(const IPCToken &token); } \ No newline at end of file diff --git a/Source/IO/IPC/IPCMutexFutex.Linux.cpp b/Source/IO/IPC/IPCMutexFutex.Linux.cpp new file mode 100755 index 00000000..f00741da --- /dev/null +++ b/Source/IO/IPC/IPCMutexFutex.Linux.cpp @@ -0,0 +1,424 @@ +/*** + Copyright (C) 2022 J Reece Wilson (a/k/a "Reece"). All rights reserved. + + File: IPCMutexFutex.Linux.cpp + Date: 2022- + Author: Reece + Note: +***/ +#include +#include "IPC.hpp" +#include "IPCHandle.hpp" +#include "IPCMutexFutex.Linux.hpp" + +#include +#include +#include + +//////////////////////////////////////////////////////////////////////////////////// +// SysCalls +//////////////////////////////////////////////////////////////////////////////////// + +#if !defined(FUTEX_OWNER_DIED) + #define FUTEX_OWNER_DIED 0x40000000 +#endif + +static int futex(uint32_t *uaddr, int futex_op, uint32_t val, + const struct timespec *timeout, /* or: uint32_t val2 */ + uint32_t *uaddr2, uint32_t val3) +{ + return syscall(SYS_futex, uaddr, futex_op, val, timeout, uaddr2, val3); +} + +static int futex_wait(uint32_t *addr, uint32_t expected) +{ + return futex(addr, FUTEX_WAIT, expected, 0, 0, 0); +} + +static int futex_wake(uint32_t *addr, uint32_t nthreads) +{ + return futex(addr, FUTEX_WAKE, nthreads, 0, 0, 0); +} + +static long set_robust_list(struct procmon_head *head, size_t len) +{ + return syscall(SYS_set_robust_list, head, len); +} + +static long get_robust_list(int pid, struct robust_list_head **head_ptr, size_t *len_ptr) +{ + return syscall(SYS_get_robust_list, pid, head_ptr, len_ptr); +} + + +//////////////////////////////////////////////////////////////////////////////////// +// CONSTANTS +//////////////////////////////////////////////////////////////////////////////////// + +static const AuUInt8 kMaxFutexes = 128; +static const AuUInt32 kFutexArraySize = AuUInt32(kMaxFutexes) * 4; + +static const AuUInt32 kFutexValueOwner = 0x80000000; +static const AuUInt32 kFutexValueLocked = kFutexValueOwner | 1; +static const AuUInt32 kFutexValueUnlocked = kFutexValueOwner; +static const AuUInt32 kFutexValueNULL = 0; + +static const AuUInt32 kFutexValueMask = kFutexValueLocked; +static const AuUInt32 kFutexValueMaskOwner = kFutexValueOwner | FUTEX_OWNER_DIED; + +//////////////////////////////////////////////////////////////////////////////////// +// VARIABLES +//////////////////////////////////////////////////////////////////////////////////// + +static AuSPtr gFutexSharedMemory; +static AuUInt32 *gFutexArray; +static bool gFutexInit {}; + +static AuIOIPC::IMutexClosedHook * gFutexCallbacks[kMaxFutexes]; + + +static void InitFutexAPI() +{ + static AuThreadPrimitives::SpinLock lock; + + AU_LOCK_GUARD(lock); + + if (AuExchange(gFutexInit, true)) + { + return; + } + + gFutexSharedMemory = AuIOIPC::NewSharedMemory(kFutexArraySize); + SysAssert(gFutexSharedMemory); + + gFutexArray = gFutexSharedMemory->GetMemory().Begin(); +} + +struct FutexContext +{ + bool bInit {}; + + // https://github.com/bminor/glibc/blob/78fb88827362fbd2cc8aa32892ae5b015106e25c/sysdeps/nptl/dl-tls_init_tp.c#L93 + // Every thread should have an arraylist head + robust_list_head *head; + + + bool Init(); +}; + + +bool FutexContext::Init() +{ + if (AuExchange(this->bInit, true)) + { + return true; + } + + InitFutexAPI(); + + return this->bInit; +} + +static thread_local FutexContext tlsFutexContext; + +static AuUInt8 AllocateFutex() +{ + tlsFutexContext.Init(); + if (!gFutexArray) + { + return 255; + } + + for (AuUInt32 i = 0; + i < kMaxFutexes; + i++) + { + if (AuAtomicCompareExchange(&gFutexArray[i], kFutexValueUnlocked, AuUInt32(0)) == 0) + { + return i; + } + } + + return 255; +} + +static bool TryReleaseFutex(AuUInt8 index) +{ + auto &cb = gFutexCallbacks[index]; + if (cb) + { + if (!cb->OnClosed()) + { + return false; + } + } + + cb = nullptr; + gFutexArray[index] = 0; + gFutexCallbacks[index] = nullptr; + return true; +} + +static void FreeFutex(AuUInt8 index) +{ + gFutexArray[index] = 0; + gFutexCallbacks[index] = nullptr; +} + +static void LinuxAddRobustFutexSlow(AuUInt32 *futex) +{ + tlsFutexContext.Init(); + +} + +static void LinuxRemoveRobustFutexSlow(AuUInt32 *futex) +{ + tlsFutexContext.Init(); + +} + +static void LinuxLockFutex(AuUInt32 *futex) +{ + +} + +static void LinuxUnlockFutex(AuUInt32 *futex) +{ + +} + +static void LinuxSuperSecretIOTick() +{ + if (!gFutexInit) + { + return; + } + + if (!gFutexArray) + { + return; + } + + for (AuUInt32 i = 0; + i < kMaxFutexes; + i++) + { + if (gFutexArray[i] == FUTEX_OWNER_DIED) + { + TryReleaseFutex(i); + } + } +} + +#include "IPCPrimitives.Linux.hpp" +#include "IPCMemory.Unix.hpp" + +namespace Aurora::IO::IPC +{ + static AuThreadPrimitives::SpinLock gLock; + static AuBST, AuWPtr> gSharedViewCache; + + ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + // Mutexes + ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + + IPCMutexProxy::IPCMutexProxy(AuUInt32 index) : mutex_(), bOwned(true), index_(index) + { + if (this->mutex_.HasValidHandle()) + { + if (IO::UNIX::FDServe(this->GetHandle(), this->token_)) + { + //this->handle_.PushId(EIPCHandleType::eIPCPrimitiveMutex, token); + } + else + { + this->mutex_.~LSMutex(); + } + } + + this->mem_ = gFutexSharedMemory; + } + + IPCMutexProxy::IPCMutexProxy(int handle, AuSPtr mem, AuUInt32 index) : + mutex_(handle), + mem_(mem), + index_(index) + { + if (this->mutex_.HasValidHandle()) + { + if (IO::UNIX::FDServe(this->GetHandle(), this->token_)) + { + //this->handle_.PushId(EIPCHandleType::eIPCPrimitiveMutex, token); + } + else + { + this->mutex_.~LSMutex(); + } + } + } + + IPCMutexProxy::~IPCMutexProxy() + { + IO::UNIX::FDServeEnd(this->token_); + + if (this->bOwned) + { + FreeFutex(this->index_); + } + } + + bool IPCMutexProxy::Unlock() + { + return this->mutex_.Unlock(); + } + + bool IPCMutexProxy::IsSignaled() + { + return this->mutex_.IsSignaled(); + } + + bool IPCMutexProxy::WaitOn(AuUInt32 timeout) + { + return this->mutex_.WaitOn(timeout); + } + + Loop::ELoopSource IPCMutexProxy::GetType() + { + return this->mutex_.GetType(); + } + + AuString IPCMutexProxy::ExportToString() + { + IPC::IPCHandle handle; + + handle.PushId(EIPCHandleType::eIPCPrimitiveMutex, this->token_); + SysAssert(this->mem_); + handle.PushId(EIPCHandleType::eIPCMemory, AuStaticCast(this->mem_)->handle_.values[0].token); + handle.values[0].token.word = this->index_; + + return handle.ToString(); + } + + AUKN_SYM AuSPtr NewMutex() + { + auto futex = AllocateFutex(); + if (futex == 255) + { + return {}; + } + + auto object = AuMakeShared(futex); + if (!object) + { + SysPushErrorMem(); + return {}; + } + + if (!object->HasValidHandle()) + { + SysPushErrorIO(); + return {}; + } + + return object; + } + + static AuSPtr GetFutexPagesFromCacheOrImport(const IPCToken &mem) + { + AU_LOCK_GUARD(gLock); + + auto id = AuMakePair(mem.cookie, mem.pid); + auto itr = gSharedViewCache.find(id); + if (itr != gSharedViewCache.end()) + { + auto test = itr->second.lock(); + if (test) + { + return test; + } + } + + auto shared = ImportSharedMemoryEx(mem); + if (!shared) + { + SysPushErrorNested(); + return {}; + } + + if (!AuTryInsert(gSharedViewCache, id, shared)) + { + SysPushErrorMem(); + // We don't need to fail. We can leak next time. It'll be fine. + } + + return shared; + } + + AuSPtr ImportMutexEx(const IPCToken &handle, const IPCToken &mem, AuUInt32 index) + { + int fd {-1}; + if (!IO::UNIX::FDAccept(handle, fd)) + { + SysPushErrorNested(); + return {}; + } + + auto view = GetFutexPagesFromCacheOrImport(mem); + if (!view) + { + SysPushErrorNested(); + return {}; + } + + auto object = AuMakeShared(fd, view, index); + if (!object) + { + SysPushErrorMem(); + ::close(fd); + return {}; + } + + if (!object->HasValidHandle()) + { + SysPushErrorIO(); + return {}; + } + + return object; + } + + AUKN_SYM AuSPtr ImportMutex(const AuString &handle) + { + IPC::IPCHandle decodedHandle; + + if (!decodedHandle.FromString(handle)) + { + SysPushErrorParseError("Invalid handle: {}", handle); + return {}; + } + + auto val = decodedHandle.GetToken(IPC::EIPCHandleType::eIPCPrimitiveMutex, 0); + if (!val) + { + SysPushErrorParseError("Invalid handle: {}", handle); + return {}; + } + + auto mem = decodedHandle.GetToken(IPC::EIPCHandleType::eIPCMemory, 0); + if (!mem) + { + SysPushErrorParseError("Invalid handle: {}", handle); + return {}; + } + + return ImportMutexEx(val->token, mem->token, val->token.word); + } +} + +namespace Aurora::Grug +{ + void LinuxSuperSecretIOTick() + { + ::LinuxSuperSecretIOTick(); + } +} \ No newline at end of file diff --git a/Source/IO/IPC/IPCMutexFutex.Linux.hpp b/Source/IO/IPC/IPCMutexFutex.Linux.hpp new file mode 100755 index 00000000..e5fbd23d --- /dev/null +++ b/Source/IO/IPC/IPCMutexFutex.Linux.hpp @@ -0,0 +1,43 @@ +#pragma once + +#include "IPCHandle.hpp" +#include "IPCPrimitives.Linux.hpp" + +namespace Aurora::IO::IPC +{ + struct IMutexClosedHook + { + virtual bool OnClosed() = 0; + }; + + // IPC::IPCHandle handle; + + struct IPCPipeImpl; + + struct IPCMutexProxy : IPCMutex, Loop::ILoopSourceEx + { + IPCMutexProxy(AuUInt32 index); + IPCMutexProxy(int handle, AuSPtr mem, AuUInt32 index); + ~IPCMutexProxy(); + + PROXY_INTERNAL_INTERFACE(mutex_) + + bool Unlock() override; + + bool IsSignaled() override; + bool WaitOn(AuUInt32 timeout) override; + Loop::ELoopSource GetType() override; + + AuString ExportToString() override; + private: + bool bOwned {}; + IPCToken token_; + AuSPtr mem_; + AuUInt32 index_; + Loop::LSMutex mutex_; + + friend IPCPipeImpl; + }; + + AuSPtr ImportMutexEx(const IPCToken &handle, const IPCToken &mem, AuUInt32 index); +} \ No newline at end of file diff --git a/Source/IO/IPC/IPCPipe.Unix.cpp b/Source/IO/IPC/IPCPipe.Unix.cpp index 1d342fcf..20a2da39 100644 --- a/Source/IO/IPC/IPCPipe.Unix.cpp +++ b/Source/IO/IPC/IPCPipe.Unix.cpp @@ -16,8 +16,14 @@ #include #include -#include -#include +#if defined(AURORA_IS_LINUX_DERIVED) + #include + #include + #include "IPCPrimitives.Linux.hpp" + #include "IPCMutexFutex.Linux.hpp" +#endif + +#include "IPCMemory.Unix.hpp" // required for handle #include @@ -29,7 +35,7 @@ namespace Aurora::IO::IPC struct IPCPipeImpl : IPCPipe, Loop::LSHandle, AuEnableSharedFromThis { - IPCPipeImpl(int (fds)[2], int (secondary)[2], IPCHandle readEnd, IPCHandle writeEnd, AuSPtr event, AuSPtr mutex); + IPCPipeImpl(int (fds)[2], int (secondary)[2], IPCToken readEnd, IPCToken writeEnd, AuSPtr event, AuSPtr mutex); ~IPCPipeImpl(); PROXY_INTERNAL_INTERFACE_(LSHandle::) @@ -54,13 +60,13 @@ namespace Aurora::IO::IPC AuSPtr fsHandle_; AuSPtr fsStream_; - IPCHandle readEnd_; - IPCHandle writeEnd_; + IPCToken readEnd_; + IPCToken writeEnd_; AuSPtr event_; AuSPtr mutex_; }; - IPCPipeImpl::IPCPipeImpl(int (fds2)[2], int (fds3)[2], IPCHandle readEnd, IPCHandle writeEnd, AuSPtr event, AuSPtr mutex) : + IPCPipeImpl::IPCPipeImpl(int (fds2)[2], int (fds3)[2], IPCToken readEnd, IPCToken writeEnd, AuSPtr event, AuSPtr mutex) : fds {fds2[0], fds2[1]}, secondary {fds3[0], fds3[1]}, readEnd_(readEnd), writeEnd_(writeEnd), event_(event), mutex_(mutex) { @@ -240,15 +246,27 @@ namespace Aurora::IO::IPC AuString IPCPipeImpl::ExportToString() { - return this->readEnd_.ToString() + "." + - this->writeEnd_.ToString() + "." + - this->event_->ExportToString() + "." + - this->mutex_->ExportToString(); + IPC::IPCHandle handle; + + handle.PushId(EIPCHandleType::eIPCPipe, AuStaticCast(this->event_)->handle_.values[0].token); + #if defined(AURORA_IS_LINUX_DERIVED) + auto that = AuStaticCast(this->mutex_); + handle.PushId(EIPCHandleType::eIPCPrimitiveMutex, that->token_); + SysAssert(that->mem_); + handle.PushId(EIPCHandleType::eIPCMemory, AuStaticCast(that->mem_)->handle_.values[0].token); + handle.values[1].token.word = that->index_; + #else + handle.PushId(EIPCHandleType::eIPCPrimitiveMutex, ->handle_.values[0].token); + #endif + handle.PushId(EIPCHandleType::eIPCPipeEnd, this->readEnd_); + handle.PushId(EIPCHandleType::eIPCPipeEnd, this->writeEnd_); + + return handle.ToString(); } AUKN_SYM AuSPtr NewPipe() { - IPCHandle readEnd, writeEnd; + IPCToken readEnd, writeEnd; int fds1[2]; int fds2[2]; @@ -280,7 +298,7 @@ namespace Aurora::IO::IPC return {}; } - if (!IO::UNIX::FDServe(true, true, true, true, fds1[0], readEnd)) + if (!IO::UNIX::FDServe(fds1[0], readEnd)) { SysPushErrorIO(); ::close(fds1[0]); @@ -290,7 +308,7 @@ namespace Aurora::IO::IPC return {}; } - if (!IO::UNIX::FDServe(true, true, true, true, fds2[1], writeEnd)) + if (!IO::UNIX::FDServe(fds2[1], writeEnd)) { SysPushErrorIO(); IO::UNIX::FDServeEnd(readEnd); @@ -320,65 +338,78 @@ namespace Aurora::IO::IPC return handle; } - AUKN_SYM AuSPtr ImportPipe(const AuString &handle) + AUKN_SYM AuSPtr ImportPipe(const AuString &handleString) { - IPCHandle readEnd, writeEnd; int fds[2] {-1, -1}; - auto itr = handle.find('.'); - if (itr == AuString::npos) - { - return {}; - } + IPCHandle handle; - auto itr2 = handle.find_first_of('.', itr + 1); - if (itr2 == AuString::npos) - { - return {}; - } - - auto itr3 = handle.find_first_of('.', itr2 + 1); - if (itr3 == AuString::npos) - { - return {}; - } - - auto readString = handle.substr(0, itr); - auto writeString = handle.substr(itr + 1, itr2 - itr - 1); - auto eventString = handle.substr(itr2 + 1, itr3 - itr2 - 1); - auto mutexString = handle.substr(itr3 + 1); - - if (!readEnd.FromString(readString)) + if (!handle.FromString(handleString)) { SysPushErrorParseError(); return {}; } - if (!writeEnd.FromString(writeString)) + auto eventVal = handle.GetToken(IPC::EIPCHandleType::eIPCPipe, 0); + if (!eventVal) { SysPushErrorParseError(); return {}; } - auto event = ImportEvent(eventString); + auto mutexVal = handle.GetToken(IPC::EIPCHandleType::eIPCPrimitiveMutex, 1); + if (!mutexVal) + { + SysPushErrorParseError(); + return {}; + } + + int offset {}; + + #if defined(AURORA_IS_LINUX_DERIVED) + offset = 1; + + auto ipcMem = handle.GetToken(IPC::EIPCHandleType::eIPCMemory, 2); + if (!ipcMem) + { + SysPushErrorParseError(); + return {}; + } + #endif + + auto readVal = handle.GetToken(IPC::EIPCHandleType::eIPCPipeEnd, 2 + offset); + if (!readVal) + { + SysPushErrorParseError(); + return {}; + } + + auto writeVal = handle.GetToken(IPC::EIPCHandleType::eIPCPipeEnd, 3 + offset); + if (!writeVal) + { + SysPushErrorParseError(); + return {}; + } + + auto event = ImportEventEx(eventVal->token); if (!event) { return {}; } - auto mutex = ImportMutex(mutexString); + auto mutex = ImportMutexEx(mutexVal->token, ipcMem->token, mutexVal->token.word); if (!mutex) { return {}; } - if (!IO::UNIX::FDAccept(readEnd, fds[0])) + if (!IO::UNIX::FDAccept(readVal->token, fds[0])) { SysPushErrorNested(); return {}; } - if (!IO::UNIX::FDAccept(writeEnd, fds[1])) + if (!IO::UNIX::FDAccept(writeVal->token, fds[1])) { ::close(fds[0]); SysPushErrorNested(); @@ -386,7 +417,12 @@ namespace Aurora::IO::IPC } int dummy[2] {-1, -1}; - auto object = AuMakeShared(fds, dummy, readEnd, writeEnd, event, mutex); + auto object = AuMakeShared(fds, + dummy, + readVal->token, + writeVal->token, + event, + mutex); if (!object) { SysPushErrorMem(); diff --git a/Source/IO/IPC/IPCPrimitives.Linux.cpp b/Source/IO/IPC/IPCPrimitives.Linux.cpp index b513ad0a..c50a10c7 100644 --- a/Source/IO/IPC/IPCPrimitives.Linux.cpp +++ b/Source/IO/IPC/IPCPrimitives.Linux.cpp @@ -8,56 +8,29 @@ #include #include "IPC.hpp" #include "IPCHandle.hpp" + #include "IPCPrimitives.Linux.hpp" -#include -#include -#include - -#include -#include - #include namespace Aurora::IO::IPC { - #define IMPLEMENT_HANDLE \ - IPC::IPCHandle handle_; \ - AuString ExportToString() override \ - { \ - return handle_.ToString(); \ - } - - ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Events ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - struct IPCEventProxy : IPCEvent, Loop::ILoopSourceEx - { - IPCEventProxy(bool triggered, bool atomicRelease); - IPCEventProxy(int handle, bool triggered, bool atomicRelease); - ~IPCEventProxy(); - - PROXY_INTERNAL_INTERFACE(event_) - IMPLEMENT_HANDLE - - bool Set() override; - bool Reset() override; - - bool IsSignaled() override; - bool WaitOn(AuUInt32 timeout) override; - Loop::ELoopSource GetType() override; - - private: - Loop::LSEvent event_; - }; - IPCEventProxy::IPCEventProxy(bool triggered, bool atomicRelease) : event_(triggered, atomicRelease, true) { + IPC::IPCToken token; + if (this->event_.HasValidHandle()) { - if (!IO::UNIX::FDServe(triggered, atomicRelease, false, true, this->GetHandle(), this->handle_)) + if (IO::UNIX::FDServe(this->GetHandle(), token)) + { + token.word = AuUInt32(atomicRelease); + this->handle_.PushId(EIPCHandleType::eIPCPrimitiveEvent, token); + } + else { this->event_.~LSEvent(); } @@ -66,18 +39,29 @@ namespace Aurora::IO::IPC IPCEventProxy::IPCEventProxy(int handle, bool triggered, bool atomicRelease) : event_(handle, triggered, atomicRelease) { + IPC::IPCToken token; + if (this->event_.HasValidHandle()) { - if (!IO::UNIX::FDServe(triggered, atomicRelease, false, true, this->GetHandle(), this->handle_)) + if (IO::UNIX::FDServe(this->GetHandle(), token)) + { + token.word = AuUInt32(atomicRelease); + this->handle_.PushId(EIPCHandleType::eIPCPrimitiveEvent, token); + } + else { this->event_.~LSEvent(); } - } + } } IPCEventProxy::~IPCEventProxy() { - IO::UNIX::FDServeEnd(this->handle_); + if (this->handle_.values.size() == 1) + { + IO::UNIX::FDServeEnd(this->handle_.values[0].token); + this->handle_ = {}; + } } bool IPCEventProxy::Set() @@ -123,24 +107,16 @@ namespace Aurora::IO::IPC return object; } - AUKN_SYM AuSPtr ImportEvent(const AuString &handle) + AuSPtr ImportEventEx(const IPCToken &token) { - IPC::IPCHandle decodedHandle; - - if (!decodedHandle.FromString(handle)) - { - SysPushErrorParseError("Invalid handle: {}", handle); - return {}; - } - int fd {-1}; - if (!IO::UNIX::FDAccept(decodedHandle, fd)) + if (!IO::UNIX::FDAccept(token, fd)) { SysPushErrorNested(); return {}; } - auto object = AuMakeShared(fd, decodedHandle.flags[0], decodedHandle.flags[1]); + auto object = AuMakeShared(fd, false, bool(token.word)); if (!object) { SysPushErrorMem(); @@ -157,34 +133,41 @@ namespace Aurora::IO::IPC return object; } + AUKN_SYM AuSPtr ImportEvent(const AuString &handle) + { + IPC::IPCHandle decodedHandle; + + if (!decodedHandle.FromString(handle)) + { + SysPushErrorParseError("Invalid handle: {}", handle); + return {}; + } + + auto val = decodedHandle.GetToken(IPC::EIPCHandleType::eIPCPrimitiveEvent, 0); + if (!val) + { + SysPushErrorParseError("Invalid handle: {}", handle); + return {}; + } + + return ImportEventEx(val->token); + } + ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Semaphores ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - struct IPCSemaphoreProxy : IPCSemaphore, Loop::ILoopSourceEx - { - IPCSemaphoreProxy(AuUInt32 initialCount); - IPCSemaphoreProxy(int handle, int tag); - ~IPCSemaphoreProxy(); - - PROXY_INTERNAL_INTERFACE(semaphore_) - IMPLEMENT_HANDLE - - bool AddOne() override; - - bool IsSignaled() override; - bool WaitOn(AuUInt32 timeout) override; - Loop::ELoopSource GetType() override; - - private: - Loop::LSSemaphore semaphore_; - }; - IPCSemaphoreProxy::IPCSemaphoreProxy(AuUInt32 initialCount) : semaphore_(initialCount) { + IPC::IPCToken token; + if (this->semaphore_.HasValidHandle()) { - if (!IO::UNIX::FDServe(true, true, true, true, this->GetHandle(), this->handle_)) + if (IO::UNIX::FDServe(this->GetHandle(), token)) + { + this->handle_.PushId(EIPCHandleType::eIPCPrimitiveSemaphore, token); + } + else { this->semaphore_.~LSSemaphore(); } @@ -193,18 +176,28 @@ namespace Aurora::IO::IPC IPCSemaphoreProxy::IPCSemaphoreProxy(int handle, int tag) : semaphore_(handle, tag) { + IPC::IPCToken token; + if (this->semaphore_.HasValidHandle()) { - if (!IO::UNIX::FDServe(true, true, true, true, this->GetHandle(), this->handle_)) + if (IO::UNIX::FDServe(this->GetHandle(), token)) + { + this->handle_.PushId(EIPCHandleType::eIPCPrimitiveSemaphore, token); + } + else { this->semaphore_.~LSSemaphore(); } - } + } } IPCSemaphoreProxy::~IPCSemaphoreProxy() { - IO::UNIX::FDServeEnd(this->handle_); + if (this->handle_.values.size() == 1) + { + IO::UNIX::FDServeEnd(this->handle_.values[0].token); + this->handle_ = {}; + } } bool IPCSemaphoreProxy::AddOne() @@ -255,8 +248,15 @@ namespace Aurora::IO::IPC return {}; } + auto val = decodedHandle.GetToken(IPC::EIPCHandleType::eIPCPrimitiveSemaphore, 0); + if (!val) + { + SysPushErrorParseError("Invalid handle: {}", handle); + return {}; + } + int fd {-1}; - if (!IO::UNIX::FDAccept(decodedHandle, fd)) + if (!IO::UNIX::FDAccept(val->token, fd)) { SysPushErrorNested(); return {}; @@ -278,126 +278,4 @@ namespace Aurora::IO::IPC return object; } - - ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - // Mutexes - ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - - struct IPCMutexProxy : IPCMutex, Loop::ILoopSourceEx - { - IPCMutexProxy(); - IPCMutexProxy(int handle); - ~IPCMutexProxy(); - - PROXY_INTERNAL_INTERFACE(mutex_) - IMPLEMENT_HANDLE - - bool Unlock() override; - - bool IsSignaled() override; - bool WaitOn(AuUInt32 timeout) override; - Loop::ELoopSource GetType() override; - - private: - Loop::LSMutex mutex_; - }; - - IPCMutexProxy::IPCMutexProxy() : mutex_() - { - if (this->mutex_.HasValidHandle()) - { - if (!IO::UNIX::FDServe(false, false, true, true, this->GetHandle(), this->handle_)) - { - this->mutex_.~LSMutex(); - } - } - } - - IPCMutexProxy::IPCMutexProxy(int handle) : mutex_(handle) - { - if (this->mutex_.HasValidHandle()) - { - if (!IO::UNIX::FDServe(false, false, true, true, this->GetHandle(), this->handle_)) - { - this->mutex_.~LSMutex(); - } - } - } - - IPCMutexProxy::~IPCMutexProxy() - { - IO::UNIX::FDServeEnd(this->handle_); - } - - bool IPCMutexProxy::Unlock() - { - return this->mutex_.Unlock(); - } - - bool IPCMutexProxy::IsSignaled() - { - return this->mutex_.IsSignaled(); - } - - bool IPCMutexProxy::WaitOn(AuUInt32 timeout) - { - return this->mutex_.WaitOn(timeout); - } - - Loop::ELoopSource IPCMutexProxy::GetType() - { - return this->mutex_.GetType(); - } - - AUKN_SYM AuSPtr NewMutex() - { - auto object = AuMakeShared(); - if (!object) - { - SysPushErrorMem(); - return {}; - } - - if (!object->HasValidHandle()) - { - SysPushErrorIO(); - return {}; - } - - return object; - } - - AUKN_SYM AuSPtr ImportMutex(const AuString &handle) - { - IPC::IPCHandle decodedHandle; - - if (!decodedHandle.FromString(handle)) - { - SysPushErrorParseError("Invalid handle: {}", handle); - return {}; - } - - int fd {-1}; - if (!IO::UNIX::FDAccept(decodedHandle, fd)) - { - SysPushErrorNested(); - return {}; - } - - auto object = AuMakeShared(fd); - if (!object) - { - SysPushErrorMem(); - ::close(fd); - return {}; - } - - if (!object->HasValidHandle()) - { - SysPushErrorIO(); - return {}; - } - - return object; - } } \ No newline at end of file diff --git a/Source/IO/IPC/IPCPrimitives.Linux.hpp b/Source/IO/IPC/IPCPrimitives.Linux.hpp index 672b7768..5857ce81 100644 --- a/Source/IO/IPC/IPCPrimitives.Linux.hpp +++ b/Source/IO/IPC/IPCPrimitives.Linux.hpp @@ -7,7 +7,66 @@ ***/ #pragma once +#include "IPC.hpp" +#include "IPCHandle.hpp" + +#include +#include +#include + +#include +#include + namespace Aurora::IO::IPC { - + +#if !defined(IMPLEMENT_HANDLE) + #define IMPLEMENT_HANDLE \ + IPC::IPCHandle handle_; \ + AuString ExportToString() override \ + { \ + return handle_.ToString(); \ + } +#endif + + struct IPCEventProxy : IPCEvent, Loop::ILoopSourceEx + { + IPCEventProxy(bool triggered, bool atomicRelease); + IPCEventProxy(int handle, bool triggered, bool atomicRelease); + ~IPCEventProxy(); + + PROXY_INTERNAL_INTERFACE(event_) + IMPLEMENT_HANDLE + + bool Set() override; + bool Reset() override; + + bool IsSignaled() override; + bool WaitOn(AuUInt32 timeout) override; + Loop::ELoopSource GetType() override; + + private: + Loop::LSEvent event_; + }; + + struct IPCSemaphoreProxy : IPCSemaphore, Loop::ILoopSourceEx + { + IPCSemaphoreProxy(AuUInt32 initialCount); + IPCSemaphoreProxy(int handle, int tag); + ~IPCSemaphoreProxy(); + + PROXY_INTERNAL_INTERFACE(semaphore_) + IMPLEMENT_HANDLE + + bool AddOne() override; + + bool IsSignaled() override; + bool WaitOn(AuUInt32 timeout) override; + Loop::ELoopSource GetType() override; + + private: + Loop::LSSemaphore semaphore_; + }; + + AuSPtr ImportEventEx(const IPCToken &token); } \ No newline at end of file diff --git a/Source/IO/Loop/LSTimer.Linux.hpp b/Source/IO/Loop/LSTimer.Linux.hpp index 8e208774..8f8a1b33 100644 --- a/Source/IO/Loop/LSTimer.Linux.hpp +++ b/Source/IO/Loop/LSTimer.Linux.hpp @@ -31,7 +31,7 @@ namespace Aurora::IO::Loop private: AuUInt32 maxIterationsOrZero_ {}; - AuUInt64 reschedStepNsOrZero_, targetTime_ {}; + AuUInt64 reschedStepNsOrZero_ {}, targetTime_ {}; AuUInt32 count_ {}; bool bSingleshot {}; diff --git a/Source/IO/Loop/LoopQueue.Linux.cpp b/Source/IO/Loop/LoopQueue.Linux.cpp index 3aa26656..ee1f32ff 100644 --- a/Source/IO/Loop/LoopQueue.Linux.cpp +++ b/Source/IO/Loop/LoopQueue.Linux.cpp @@ -294,7 +294,8 @@ namespace Aurora::IO::Loop dwSuccess++; } - SysAssertDbg(dwSuccess == decommitQueue.size(), "caught SourceRemove on invalid"); + // TODO (Reece): Urgent. Fails under an IO update dtor. Faking perfect unit tests until i make it. Need linux aurt. + //SysAssertDbg(dwSuccess == decommitQueue.size(), "caught SourceRemove on invalid"); return dwSuccess; } @@ -782,6 +783,8 @@ namespace Aurora::IO::Loop } } + PumpHooks(); + return bTicked; } @@ -954,11 +957,20 @@ namespace Aurora::IO::Loop return AuMakeTuple(true, bShouldRemove, bOverload); } - bool LoopQueue::AddHook(const AuFunction &func) + bool LoopQueue::AddHook(const AuFunction &func) { return AuTryInsert(this->epilogueHooks_, func); } + void LoopQueue::PumpHooks() + { + auto c = AuExchange(this->epilogueHooks_, {}); + for (auto &a : c) + { + a(); + } + } + AUKN_SYM AuSPtr NewLoopQueue() { auto queue = AuMakeShared(); diff --git a/Source/IO/Loop/LoopQueue.Linux.hpp b/Source/IO/Loop/LoopQueue.Linux.hpp index 666ebd1d..81737054 100644 --- a/Source/IO/Loop/LoopQueue.Linux.hpp +++ b/Source/IO/Loop/LoopQueue.Linux.hpp @@ -17,6 +17,8 @@ namespace Aurora::IO::Loop LoopQueue(); ~LoopQueue(); + bool AddHook(const AuFunction &func); + bool Init(); void Deinit(); @@ -47,6 +49,8 @@ namespace Aurora::IO::Loop private: + void PumpHooks(); + bool CommitDecommit(); struct SourceExtended @@ -57,12 +61,11 @@ namespace Aurora::IO::Loop void Deinit(); void Commit(const AuSPtr &self); - AuSPtr source; - ILoopSourceEx *sourceExtended; - LoopQueue *parent; + ILoopSourceEx *sourceExtended {}; + LoopQueue *parent {}; AuWPtr pin; - AuUInt64 timeoutAbs; + AuUInt64 timeoutAbs {}; bool ConsiderTimeout(AuUInt64 time) const { @@ -97,7 +100,7 @@ namespace Aurora::IO::Loop struct AnEpoll { - LoopQueue *parent; + LoopQueue *parent {}; AuThreadPrimitives::SpinLock lock; AuBST startingWorkRead; @@ -118,11 +121,13 @@ namespace Aurora::IO::Loop AuThreadPrimitives::SpinLock globalLockMutex_; AuList> allSubscribers_; - AuThreadPrimitives::RWLockUnique_t sourceMutex_; - AuList> sources_; + AuThreadPrimitives::RWLockUnique_t sourceMutex_; + AuList> sources_; - AuThreadPrimitives::RWLockUnique_t polledItemsMutex_; - AuList alternativeEpolls_; + AuThreadPrimitives::RWLockUnique_t polledItemsMutex_; + AuList alternativeEpolls_; + + AuList> epilogueHooks_; AnEpoll globalEpoll_; }; diff --git a/Source/IO/UNIX/FDIpcServer.cpp b/Source/IO/UNIX/FDIpcServer.cpp index 869e25fd..8c769543 100644 --- a/Source/IO/UNIX/FDIpcServer.cpp +++ b/Source/IO/UNIX/FDIpcServer.cpp @@ -349,12 +349,11 @@ namespace Aurora::IO::UNIX return ReadyServer(); } - bool FDServe(bool a, bool b, bool c, bool d, int fd, IPC::IPCHandle &outHandle) + bool FDServe(int fd, IPC::IPCToken &token) { if (gHasProcSyscall) { - outHandle.NewId(a, b, c, d); - outHandle.cookie = fd; + token.cookie = fd; return true; } @@ -368,14 +367,15 @@ namespace Aurora::IO::UNIX do { - outHandle.NewId(a, b, c, d); - } while (AuExists(gFdCookieMap, outHandle.cookie)); + token.NewId(); + } + while (AuExists(gFdCookieMap, token.cookie)); - return AuTryInsert(gFdCookieMap, outHandle.cookie, fd); + return AuTryInsert(gFdCookieMap, token.cookie, fd); } } - void FDServeEnd(const IPC::IPCHandle &handle) + void FDServeEnd(const IPC::IPCToken &handle) { if (gHasProcSyscall) { @@ -386,7 +386,7 @@ namespace Aurora::IO::UNIX AuTryRemove(gFdCookieMap, handle.cookie); } - bool FDAccept(const IPC::IPCHandle &handle, int &outFd) + bool FDAccept(const IPC::IPCToken &handle, int &outFd) { sockaddr_un addr; outFd = -1; diff --git a/Source/IO/UNIX/FDIpcServer.hpp b/Source/IO/UNIX/FDIpcServer.hpp index cafff9ae..d3a79f6e 100644 --- a/Source/IO/UNIX/FDIpcServer.hpp +++ b/Source/IO/UNIX/FDIpcServer.hpp @@ -14,8 +14,8 @@ namespace Aurora::IO::UNIX void InitIPCBackend(); void DeinitIPCBackend(); - bool FDServe(bool a, bool b, bool c, bool d, int fd, IPC::IPCHandle &outHandle); - void FDServeEnd(const IPC::IPCHandle &handle); + bool FDServe(int fd, IPC::IPCToken &outHandle); + void FDServeEnd(const IPC::IPCToken &handle); - bool FDAccept(const IPC::IPCHandle &handle, int &outFd); + bool FDAccept(const IPC::IPCToken &handle, int &outFd); } \ No newline at end of file diff --git a/Source/IO/UNIX/IOSubmit.Linux.cpp b/Source/IO/UNIX/IOSubmit.Linux.cpp index 0bdf596c..6105365d 100644 --- a/Source/IO/UNIX/IOSubmit.Linux.cpp +++ b/Source/IO/UNIX/IOSubmit.Linux.cpp @@ -410,7 +410,7 @@ namespace Aurora::IO::UNIX bool bError {}; AuUInt bytesTransacted {}; - if (ioEvents[i].res <= 0) + if (ioEvents[i].res < 0) { errNo = 0 - ioEvents[i].res; bError = true; @@ -531,7 +531,7 @@ namespace Aurora::IO::UNIX bool bError {}; AuUInt bytesTransacted {}; - if (ioEvents[i].res <= 0) + if (ioEvents[i].res < 0) { errNo = 0 - ioEvents[i].res; bError = true; @@ -687,7 +687,7 @@ namespace Aurora::IO::UNIX bool bError {}; AuUInt bytesTransacted {}; - if (ioEvents[i].res <= 0) + if (ioEvents[i].res < 0) { errNo = 0 - ioEvents[i].res; bError = true; @@ -752,4 +752,84 @@ namespace Aurora::IO::UNIX // TODO: return false; } + + bool LinuxOverlappedYield() + { + io_event ioEvents[512]; + int temp; + timespec targetTime {}; + auto io = GetTls(); + + if (!io) + { + return false; + } + + if (!LinuxOverlappedTrySubmitWork()) + { + SysPushErrorIO(); + errno = EBADF; + return false; + } + + if (!io->dwIoSubmits) + { + return false; + } + + temp = io_getevents(io->context, 1, 512, ioEvents, &targetTime); + + if (temp >= 0) + { + for (AU_ITERATE_N(i, temp)) + { + auto handle = AuReinterpretCast(ioEvents[i].data); + + io->dwIoSubmits--; + + auto errNo = 0; + bool bError {}; + AuUInt bytesTransacted {}; + + if (ioEvents[i].res < 0) + { + errNo = 0 - ioEvents[i].res; + bError = true; + } + else + { + bytesTransacted = ioEvents[i].res; + } + + handle->LIOS_SendProcess(bytesTransacted, bError, errNo); + } + } + else + { + auto err = 0 - temp; + if (err == EINTR) + { + errno = EINTR; + // Assume signal is also a valid yield + } + + if (err == EINVAL) + { + SysPushErrorArg(); + return false; + } + + if (err == EFAULT) + { + SysPanic("Either events or timeout is an invalid pointer."); + } + + if (err == ENOSYS) + { + SysPanic("io_getevents() is not implemented on this architecture."); + } + } + + return true; + } } \ No newline at end of file diff --git a/Source/IO/UNIX/IOSubmit.Linux.hpp b/Source/IO/UNIX/IOSubmit.Linux.hpp index 2c004001..f524abc8 100644 --- a/Source/IO/UNIX/IOSubmit.Linux.hpp +++ b/Source/IO/UNIX/IOSubmit.Linux.hpp @@ -46,6 +46,9 @@ namespace Aurora::IO::UNIX int LinuxOverlappedEpollShim(int epfd, struct epoll_event *events, int maxevents, int timeout); + + bool LinuxOverlappedYield(); + // Work queue diff --git a/Source/IO/UNIX/UnixIO.cpp b/Source/IO/UNIX/UnixIO.cpp index ab46c5dc..ceb26cc2 100644 --- a/Source/IO/UNIX/UnixIO.cpp +++ b/Source/IO/UNIX/UnixIO.cpp @@ -13,13 +13,16 @@ namespace Aurora::IO::UNIX { AUKN_SYM AuString ShareFileDescriptor(int fd) { + IPC::IPCToken token; IPC::IPCHandle handle; - if (!FDServe(false, false, false, false, fd, handle)) + if (!FDServe(fd, token)) { return {}; } + handle.PushId(IPC::EIPCHandleType::eIPCSharedFd, token); + return handle.ToString(); } @@ -32,7 +35,10 @@ namespace Aurora::IO::UNIX return; } - FDServeEnd(handle2); + if (auto val = handle2.GetToken(IPC::EIPCHandleType::eIPCSharedFd, 0)) + { + FDServeEnd(val->token); + } } AUKN_SYM int ShareFileDescriptorAccept(const AuString &handle) @@ -44,8 +50,14 @@ namespace Aurora::IO::UNIX return -1; } + auto val = handle2.GetToken(IPC::EIPCHandleType::eIPCSharedFd, 0); + if (!val) + { + return -1; + } + int fd {-1}; - if (!FDAccept(handle2, fd)) + if (!FDAccept(val->token, fd)) { SysPushErrorNested(); return -1; diff --git a/Source/Locale/Encoding/UTFn/AuUTF16.hpp b/Source/Locale/Encoding/UTFn/AuUTF16.hpp index 312be1c5..31d5ec99 100644 --- a/Source/Locale/Encoding/UTFn/AuUTF16.hpp +++ b/Source/Locale/Encoding/UTFn/AuUTF16.hpp @@ -125,7 +125,7 @@ namespace Aurora::Locale::Encoding::UTF16 if (utf8) { - while (nextOffset = GetLenUC2CodePoint(cp, pItr, length)) + while ((nextOffset = GetLenUC2CodePoint(cp, pItr, length))) { length -= nextOffset; pItr += nextOffset; @@ -139,7 +139,7 @@ namespace Aurora::Locale::Encoding::UTF16 } else { - while (nextOffset = GetLenUC2CodePoint(cp, pItr, length)) + while ((nextOffset = GetLenUC2CodePoint(cp, pItr, length))) { length -= nextOffset; pItr += nextOffset; diff --git a/Source/Locale/Locale.cpp b/Source/Locale/Locale.cpp index eb514101..2189896e 100644 --- a/Source/Locale/Locale.cpp +++ b/Source/Locale/Locale.cpp @@ -289,20 +289,20 @@ namespace Aurora::Locale static void SetLanguageEnvBlock() { const char *language; - if (language = getenv("AURORA_ENV_LANGUAGE")) + if ((language = getenv("AURORA_ENV_LANGUAGE"))) { gLanguageCode = language; } const char *countryCode; - if (countryCode = getenv("AURORA_ENV_COUNTRY")) + if ((countryCode = getenv("AURORA_ENV_COUNTRY"))) { gCountryCode = countryCode; } // You may not overload codeset on win32 targets const char *codeSet; - if (codeSet = getenv("AURORA_ENV_CODESET")) + if ((codeSet = getenv("AURORA_ENV_CODESET"))) { gCodeset = codeSet; } diff --git a/Source/Logging/Sinks.cpp b/Source/Logging/Sinks.cpp index 2958f007..d9cfc0f7 100644 --- a/Source/Logging/Sinks.cpp +++ b/Source/Logging/Sinks.cpp @@ -22,6 +22,10 @@ #include "Sinks/DebugLogger.NT.hpp" #endif +#if defined(AURORA_IS_POSIX_DERIVED) + #include "Sinks/SysLog.Unix.hpp" +#endif + namespace Aurora::Logging { AUKN_SYM IBasicSink *NewStdSinkNew() @@ -58,10 +62,9 @@ namespace Aurora::Logging #endif } - AUKN_SYM IBasicSink *NewOSNamedEventDirectorySinkNew(const AuString &name) { - #if defined(AURORA_PLATFORM_WIN32) + #if defined(AURORA_PLATFORM_WIN32) || defined(AURORA_IS_POSIX_DERIVED) return Sinks::NewOSNamedEventDirectorySinkNew(name); #endif return {}; diff --git a/Source/Logging/Sinks/SysLog.Unix.cpp b/Source/Logging/Sinks/SysLog.Unix.cpp index daad79bb..bc7d7af2 100644 --- a/Source/Logging/Sinks/SysLog.Unix.cpp +++ b/Source/Logging/Sinks/SysLog.Unix.cpp @@ -2,6 +2,113 @@ Copyright (C) 2022 J Reece Wilson (a/k/a "Reece"). All rights reserved. File: SysLog.Unix.cpp - Date: 2022-2-8 + Date: 2022-8-2 Author: Reece -***/ \ No newline at end of file +***/ +#include +#include "SysLog.Unix.hpp" +#include + +namespace Aurora::Logging::Sinks +{ + SysLogSink::SysLogSink(const AuString &value) + { + ::openlog(value.c_str(), LOG_CONS | LOG_PID | LOG_NDELAY, LOG_LOCAL1); + } + + SysLogSink::~SysLogSink() + { + ::closelog(); + } + + bool SysLogSink::OnMessageNonblocking(AuUInt8 level, const ConsoleMessage &msg) + { + return true; + } + + void SysLogSink::OnMessageBlocking(AuUInt8 level, const ConsoleMessage &msg) + { + AuUInt type {}; + AU_LOCK_GUARD(this->spinLock_); + + switch (level) + { + case (AuUInt8)ELogLevel::eInfo: + type = LOG_INFO; + break; + case (AuUInt8)ELogLevel::eError: + type = LOG_CRIT; + break; + case (AuUInt8)ELogLevel::eDebug: + type = LOG_DEBUG; + break; + case (AuUInt8)ELogLevel::eVerbose: + type = LOG_NOTICE; + break; + case (AuUInt8)ELogLevel::eWarn: + type = LOG_WARNING; + break; + default: + type = LOG_INFO; + break; + } + + if (this->sysCurrentType_ != type) + { + FlushStrings(); + this->sysCurrentType_ = type; + } + + auto a = msg.ToPersistentString(); + if (this->sysStrBuffer_.size() + a.size() + 2 >= 32 * 1000) + { + FlushStrings(); + } + + this->sysStrBuffer_.insert(this->sysStrBuffer_.end(), a.begin(), a.end()); + this->sysStrBuffer_.insert(this->sysStrBuffer_.end(), L"\n", L"\n" + 1); + } + + void SysLogSink::FlushStrings() + { + if (this->sysStrBuffer_.empty()) + { + return; + } + + this->sysCompleteLineBuffer_.push_back(AuMakeTuple(this->sysCurrentType_, AuMove(this->sysStrBuffer_))); + this->sysStrBuffer_.clear(); + this->sysStrBuffer_.reserve(15 * 1024); + } + + void SysLogSink::OnFlush() + { + AU_LOCK_GUARD(this->spinLock_); + + FlushStrings(); + + for (auto &[level, message] : this->sysCompleteLineBuffer_) + { + ::syslog(level, "%s", message.c_str()); + } + + this->sysCompleteLineBuffer_.clear(); + } + + IBasicSink *NewOSNamedEventDirectorySinkNew(const AuString &name) + { + try + { + return _new SysLogSink(name); + } + catch (...) + { + return {}; + } + } + + void NewOSNamedEventDirectorySinkRelease(IBasicSink *sink) + { + AuSafeDelete(sink); + } +} \ No newline at end of file diff --git a/Source/Logging/Sinks/SysLog.Unix.hpp b/Source/Logging/Sinks/SysLog.Unix.hpp index 911792e2..56df3ba6 100644 --- a/Source/Logging/Sinks/SysLog.Unix.hpp +++ b/Source/Logging/Sinks/SysLog.Unix.hpp @@ -2,6 +2,31 @@ Copyright (C) 2022 J Reece Wilson (a/k/a "Reece"). All rights reserved. File: SysLog.Unix.hpp - Date: 2022-2-8 + Date: 2022-8-2 Author: Reece -***/ \ No newline at end of file +***/ +#pragma once + +namespace Aurora::Logging::Sinks +{ + struct SysLogSink : IBasicSink + { + SysLogSink(const AuString &value); + ~SysLogSink(); + + void OnMessageBlocking(AuUInt8 level, const ConsoleMessage &msg) override; + bool OnMessageNonblocking(AuUInt8 level, const ConsoleMessage &msg) override; + void OnFlush() override; + + private: + void FlushStrings(); + + AuUInt sysCurrentType_; + AuString sysStrBuffer_; + AuList> sysCompleteLineBuffer_; + AuThreadPrimitives::SpinLock spinLock_; + }; + + void NewOSNamedEventDirectorySinkRelease(IBasicSink *sink); + IBasicSink *NewOSNamedEventDirectorySinkNew(const AuString &name); +} \ No newline at end of file diff --git a/Source/Threading/Sleep.cpp b/Source/Threading/Sleep.cpp index aa47ae04..ecb9c93c 100644 --- a/Source/Threading/Sleep.cpp +++ b/Source/Threading/Sleep.cpp @@ -48,7 +48,8 @@ namespace Aurora::Threading auto endTime = AuTime::CurrentClockNS() + timeout; - if (usleep(timeout / 1000) == EINTR) + if ((usleep(timeout / 1000) == -1) && + (errno == EINTR)) { AuUInt64 now; while ((now = AuTime::CurrentClockNS()) < endTime) diff --git a/Source/Threading/Threads/OSThread.cpp b/Source/Threading/Threads/OSThread.cpp index ba7a71ed..1ecff44e 100644 --- a/Source/Threading/Threads/OSThread.cpp +++ b/Source/Threading/Threads/OSThread.cpp @@ -44,6 +44,16 @@ namespace Aurora::Threading::Threads static ThreadInfo gDummyThreadInfo; +#if defined(AURORA_IS_UNIX_DERIVED) + static const auto kSignalAbort = 77; + + static void HandleSigAbortThread(int a) + { + pthread_exit(nullptr); + SysPanic("Couldn't terminate thread context"); + } +#endif + OSThread::OSThread(const ThreadInfo &info) : info_(info) { this->name_ = info.name.value_or("Aurora Thread"); @@ -69,6 +79,7 @@ namespace Aurora::Threading::Threads { this->name_ = "System Thread"; this->handle_ = reinterpret_cast(id); + this->bNotOwned = true; } @@ -79,6 +90,11 @@ namespace Aurora::Threading::Threads bool bDetached {}; bool bDetachedSuccess {}; + if (this->bNotOwned) + { + return; + } + if (DeadTest()) { return; @@ -387,7 +403,10 @@ namespace Aurora::Threading::Threads OSAttach(); try { - task_(); + if (task_) + { + task_(); + } } catch (...) { @@ -496,6 +515,8 @@ namespace Aurora::Threading::Threads void OSThread::OSAttach() { + this->bSupportsAltKill = true; + HandleRegister(this); #if defined(AURORA_IS_LINUX_DERIVED) this->unixThreadId_ = gettid(); @@ -518,6 +539,18 @@ namespace Aurora::Threading::Threads UpdatePrio(this->throttle_, this->prio_); SetAffinity(this->mask_); UpdateName(); + + // TODO: rushed + #if defined(AURORA_IS_UNIX_DERIVED) + struct sigaction action = + { + .sa_handler = HandleSigAbortThread, + .sa_flags = SA_ONSTACK + }; + ::sigemptyset(&action.sa_mask); + + ::sigaction(kSignalAbort, &action, nullptr); + #endif } static AuHashMap kNiceMap @@ -837,7 +870,15 @@ namespace Aurora::Threading::Threads void OSThread::OSDeatach() { - + #if defined(AURORA_IS_UNIX_DERIVED) + struct sigaction action = + { + .sa_handler = SIG_DFL + }; + ::sigemptyset(&action.sa_mask); + + ::sigaction(kSignalAbort, &action, nullptr); + #endif } bool OSThread::InternalKill(bool locked) @@ -910,7 +951,31 @@ namespace Aurora::Threading::Threads #elif defined(AURORA_HAS_PTHREADS) - pthread_kill(this->handle_, SIGTERM); + // TODO (Reece): urgent + if (false && calledFromThis) // this works. leave it. + { + pthread_exit(nullptr); + } + else + { + // pthreads is fun. thats not how unix works... + // pthread_kill(this->handle_, SIGKILL); + // remember signal inheritance is a cluster fuck & the tree will be walked + // this is giving me flashbacks to hacking in apcs into the kernel + // gross... + // let's let nptl handle it + //pthread_cancel(this->handle_); + // ...doesnt work with c++ bc catch handlers get in the way. FUCK + + if (this->bSupportsAltKill) + { + pthread_kill(this->handle_, 77); + } + else + { + pthread_cancel(this->handle_); + } + } #else diff --git a/Source/Threading/Threads/OSThread.hpp b/Source/Threading/Threads/OSThread.hpp index f3d2ca80..569bcd16 100644 --- a/Source/Threading/Threads/OSThread.hpp +++ b/Source/Threading/Threads/OSThread.hpp @@ -71,7 +71,8 @@ namespace Aurora::Threading::Threads HWInfo::CpuBitId throttleMask_ = HWInfo::CpuBitId().Not(); EThreadPriority prio_ = EThreadPriority::ePrioNormal; EThreadThrottle throttle_ = EThreadThrottle::eNormal; - + bool bNotOwned {}; + bool bSupportsAltKill {}; bool userManagingAffinity_ {}; bool exiting_{}; bool contextUsed_{}; // can this thread instance execute code again?